cd4c9f82fc
We now support only Python 3.7+, this means we can rely on dict being ordered by order of insertion, and thus no need to use OrderedDict from collections.
1251 lines
36 KiB
Python
1251 lines
36 KiB
Python
import unittest
|
|
from slixmpp.test import SlixTest
|
|
from slixmpp.xmlstream.stanzabase import ElementBase, register_stanza_plugin, ET
|
|
|
|
|
|
class TestElementBase(SlixTest):
|
|
|
|
def testFixNs(self):
|
|
"""Test fixing namespaces in an XPath expression."""
|
|
|
|
e = ElementBase()
|
|
ns = "http://jabber.org/protocol/disco#items"
|
|
result = e._fix_ns("{%s}foo/bar/{abc}baz/{%s}more" % (ns, ns))
|
|
|
|
expected = "/".join(["{%s}foo" % ns,
|
|
"{%s}bar" % ns,
|
|
"{abc}baz",
|
|
"{%s}more" % ns])
|
|
self.assertTrue(expected == result,
|
|
"Incorrect namespace fixing result: %s" % str(result))
|
|
|
|
|
|
def testExtendedName(self):
|
|
"""Test element names of the form tag1/tag2/tag3."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo/bar/baz"
|
|
namespace = "test"
|
|
|
|
stanza = TestStanza()
|
|
self.check(stanza, """
|
|
<foo xmlns="test">
|
|
<bar>
|
|
<baz />
|
|
</bar>
|
|
</foo>
|
|
""")
|
|
|
|
def testGetStanzaValues(self):
|
|
"""Test get_stanza_values using plugins and substanzas."""
|
|
|
|
class TestStanzaPlugin(ElementBase):
|
|
name = "foo2"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
plugin_attrib = "foo2"
|
|
|
|
class TestSubStanza(ElementBase):
|
|
name = "subfoo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
register_stanza_plugin(TestStanza, TestStanzaPlugin, iterable=True)
|
|
|
|
stanza = TestStanza()
|
|
stanza['bar'] = 'a'
|
|
stanza['foo2']['baz'] = 'b'
|
|
substanza = TestSubStanza()
|
|
substanza['bar'] = 'c'
|
|
stanza.append(substanza)
|
|
|
|
values = stanza.get_stanza_values()
|
|
expected = {'lang': '',
|
|
'bar': 'a',
|
|
'baz': '',
|
|
'foo2': {'lang': '',
|
|
'bar': '',
|
|
'baz': 'b'},
|
|
'substanzas': [{'__childtag__': '{foo}foo2',
|
|
'lang': '',
|
|
'bar': '',
|
|
'baz': 'b'},
|
|
{'__childtag__': '{foo}subfoo',
|
|
'lang': '',
|
|
'bar': 'c',
|
|
'baz': ''}]}
|
|
self.assertTrue(values == expected,
|
|
"Unexpected stanza values:\n%s\n%s" % (str(expected), str(values)))
|
|
|
|
|
|
def testSetStanzaValues(self):
|
|
"""Test using set_stanza_values with substanzas and plugins."""
|
|
|
|
class TestStanzaPlugin(ElementBase):
|
|
name = "pluginfoo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
plugin_attrib = "plugin_foo"
|
|
|
|
class TestStanzaPlugin2(ElementBase):
|
|
name = "pluginfoo2"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
plugin_attrib = "plugin_foo2"
|
|
|
|
class TestSubStanza(ElementBase):
|
|
name = "subfoo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
register_stanza_plugin(TestStanza, TestSubStanza, iterable=True)
|
|
register_stanza_plugin(TestStanza, TestStanzaPlugin)
|
|
register_stanza_plugin(TestStanza, TestStanzaPlugin2)
|
|
|
|
stanza = TestStanza()
|
|
values = {'bar': 'a',
|
|
'baz': '',
|
|
'plugin_foo': {'bar': '',
|
|
'baz': 'b'},
|
|
'plugin_foo2': {'bar': 'd',
|
|
'baz': 'e'},
|
|
'substanzas': [{'__childtag__': '{foo}subfoo',
|
|
'bar': 'c',
|
|
'baz': ''}]}
|
|
stanza.values = values
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo" bar="a">
|
|
<pluginfoo baz="b" />
|
|
<pluginfoo2 bar="d" baz="e" />
|
|
<subfoo bar="c" />
|
|
</foo>
|
|
""")
|
|
|
|
def testGetItem(self):
|
|
"""Test accessing stanza interfaces."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz', 'qux'}
|
|
sub_interfaces = {'baz'}
|
|
|
|
def get_qux(self):
|
|
return 'qux'
|
|
|
|
class TestStanzaPlugin(ElementBase):
|
|
name = "foobar"
|
|
namespace = "foo"
|
|
plugin_attrib = "foobar"
|
|
interfaces = {'fizz'}
|
|
|
|
register_stanza_plugin(TestStanza, TestStanza, iterable=True)
|
|
register_stanza_plugin(TestStanza, TestStanzaPlugin)
|
|
|
|
stanza = TestStanza()
|
|
substanza = TestStanza()
|
|
stanza.append(substanza)
|
|
stanza.set_stanza_values({'bar': 'a',
|
|
'baz': 'b',
|
|
'qux': 42,
|
|
'foobar': {'fizz': 'c'}})
|
|
|
|
# Test non-plugin interfaces
|
|
expected = {'substanzas': [substanza],
|
|
'bar': 'a',
|
|
'baz': 'b',
|
|
'qux': 'qux',
|
|
'meh': ''}
|
|
for interface, value in expected.items():
|
|
result = stanza[interface]
|
|
self.assertTrue(result == value,
|
|
"Incorrect stanza interface access result: %s" % result)
|
|
|
|
# Test plugin interfaces
|
|
self.assertTrue(isinstance(stanza['foobar'], TestStanzaPlugin),
|
|
"Incorrect plugin object result.")
|
|
self.assertTrue(stanza['foobar']['fizz'] == 'c',
|
|
"Incorrect plugin subvalue result.")
|
|
|
|
def testSetItem(self):
|
|
"""Test assigning to stanza interfaces."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz', 'qux'}
|
|
sub_interfaces = {'baz'}
|
|
|
|
def set_qux(self, value):
|
|
pass
|
|
|
|
class TestStanzaPlugin(ElementBase):
|
|
name = "foobar"
|
|
namespace = "foo"
|
|
plugin_attrib = "foobar"
|
|
interfaces = {'foobar'}
|
|
|
|
register_stanza_plugin(TestStanza, TestStanzaPlugin)
|
|
|
|
stanza = TestStanza()
|
|
|
|
stanza['bar'] = 'attribute!'
|
|
stanza['baz'] = 'element!'
|
|
stanza['qux'] = 'overridden'
|
|
stanza['foobar'] = 'plugin'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo" bar="attribute!">
|
|
<baz>element!</baz>
|
|
<foobar foobar="plugin" />
|
|
</foo>
|
|
""")
|
|
|
|
def testDelItem(self):
|
|
"""Test deleting stanza interface values."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz', 'qux'}
|
|
sub_interfaces = {'bar'}
|
|
|
|
def del_qux(self):
|
|
pass
|
|
|
|
class TestStanzaPlugin(ElementBase):
|
|
name = "foobar"
|
|
namespace = "foo"
|
|
plugin_attrib = "foobar"
|
|
interfaces = {'foobar'}
|
|
|
|
register_stanza_plugin(TestStanza, TestStanzaPlugin)
|
|
|
|
stanza = TestStanza()
|
|
stanza['bar'] = 'a'
|
|
stanza['baz'] = 'b'
|
|
stanza['qux'] = 'c'
|
|
stanza['foobar']['foobar'] = 'd'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo" baz="b" qux="c">
|
|
<bar>a</bar>
|
|
<foobar foobar="d" />
|
|
</foo>
|
|
""")
|
|
|
|
del stanza['bar']
|
|
del stanza['baz']
|
|
del stanza['qux']
|
|
del stanza['foobar']
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo" qux="c" />
|
|
""")
|
|
|
|
def testModifyingAttributes(self):
|
|
"""Test modifying top level attributes of a stanza's XML object."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
stanza = TestStanza()
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo" />
|
|
""")
|
|
|
|
self.assertTrue(stanza._get_attr('bar') == '',
|
|
"Incorrect value returned for an unset XML attribute.")
|
|
|
|
stanza._set_attr('bar', 'a')
|
|
stanza._set_attr('baz', 'b')
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo" bar="a" baz="b" />
|
|
""")
|
|
|
|
self.assertTrue(stanza._get_attr('bar') == 'a',
|
|
"Retrieved XML attribute value is incorrect.")
|
|
|
|
stanza._set_attr('bar', None)
|
|
stanza._del_attr('baz')
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo" />
|
|
""")
|
|
|
|
self.assertTrue(stanza._get_attr('bar', 'c') == 'c',
|
|
"Incorrect default value returned for an unset XML attribute.")
|
|
|
|
def testGetSubText(self):
|
|
"""Test retrieving the contents of a sub element."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar'}
|
|
|
|
def set_bar(self, value):
|
|
wrapper = ET.Element("{foo}wrapper")
|
|
bar = ET.Element("{foo}bar")
|
|
bar.text = value
|
|
wrapper.append(bar)
|
|
self.xml.append(wrapper)
|
|
|
|
def get_bar(self):
|
|
return self._get_sub_text("wrapper/bar", default="not found")
|
|
|
|
stanza = TestStanza()
|
|
self.assertTrue(stanza['bar'] == 'not found',
|
|
"Default _get_sub_text value incorrect.")
|
|
|
|
stanza['bar'] = 'found'
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<wrapper>
|
|
<bar>found</bar>
|
|
</wrapper>
|
|
</foo>
|
|
""")
|
|
self.assertTrue(stanza['bar'] == 'found',
|
|
"_get_sub_text value incorrect: %s." % stanza['bar'])
|
|
|
|
def testSubElement(self):
|
|
"""Test setting the contents of a sub element."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
def set_baz(self, value):
|
|
self._set_sub_text("wrapper/baz", text=value)
|
|
|
|
def get_baz(self):
|
|
return self._get_sub_text("wrapper/baz")
|
|
|
|
def set_bar(self, value):
|
|
self._set_sub_text("wrapper/bar", text=value)
|
|
|
|
def get_bar(self):
|
|
return self._get_sub_text("wrapper/bar")
|
|
|
|
stanza = TestStanza()
|
|
stanza['bar'] = 'a'
|
|
stanza['baz'] = 'b'
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<wrapper>
|
|
<bar>a</bar>
|
|
<baz>b</baz>
|
|
</wrapper>
|
|
</foo>
|
|
""")
|
|
stanza._set_sub_text('wrapper/bar', text='', keep=True)
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<wrapper>
|
|
<bar />
|
|
<baz>b</baz>
|
|
</wrapper>
|
|
</foo>
|
|
""", use_values=False)
|
|
|
|
stanza['bar'] = 'a'
|
|
stanza._set_sub_text('wrapper/bar', text='')
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<wrapper>
|
|
<baz>b</baz>
|
|
</wrapper>
|
|
</foo>
|
|
""")
|
|
|
|
def testDelSub(self):
|
|
"""Test removing sub elements."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
def set_bar(self, value):
|
|
self._set_sub_text("path/to/only/bar", value)
|
|
|
|
def get_bar(self):
|
|
return self._get_sub_text("path/to/only/bar")
|
|
|
|
def del_bar(self):
|
|
self._del_sub("path/to/only/bar")
|
|
|
|
def set_baz(self, value):
|
|
self._set_sub_text("path/to/just/baz", value)
|
|
|
|
def get_baz(self):
|
|
return self._get_sub_text("path/to/just/baz")
|
|
|
|
def del_baz(self):
|
|
self._del_sub("path/to/just/baz")
|
|
|
|
stanza = TestStanza()
|
|
stanza['bar'] = 'a'
|
|
stanza['baz'] = 'b'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<path>
|
|
<to>
|
|
<only>
|
|
<bar>a</bar>
|
|
</only>
|
|
<just>
|
|
<baz>b</baz>
|
|
</just>
|
|
</to>
|
|
</path>
|
|
</foo>
|
|
""")
|
|
|
|
del stanza['bar']
|
|
del stanza['baz']
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<path>
|
|
<to>
|
|
<only />
|
|
<just />
|
|
</to>
|
|
</path>
|
|
</foo>
|
|
""", use_values=False)
|
|
|
|
stanza['bar'] = 'a'
|
|
stanza['baz'] = 'b'
|
|
|
|
stanza._del_sub('path/to/only/bar', all=True)
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<path>
|
|
<to>
|
|
<just>
|
|
<baz>b</baz>
|
|
</just>
|
|
</to>
|
|
</path>
|
|
</foo>
|
|
""")
|
|
|
|
def testMatch(self):
|
|
"""Test matching a stanza against an XPath expression."""
|
|
|
|
class TestSubStanza(ElementBase):
|
|
name = "sub"
|
|
namespace = "baz"
|
|
interfaces = {'attrib'}
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar','baz', 'qux'}
|
|
sub_interfaces = {'qux'}
|
|
|
|
def set_qux(self, value):
|
|
self._set_sub_text('qux', text=value)
|
|
|
|
def get_qux(self):
|
|
return self._get_sub_text('qux')
|
|
|
|
class TestStanzaPlugin(ElementBase):
|
|
name = "plugin"
|
|
namespace = "http://test/slash/bar"
|
|
interfaces = {'attrib'}
|
|
|
|
register_stanza_plugin(TestStanza, TestSubStanza, iterable=True)
|
|
register_stanza_plugin(TestStanza, TestStanzaPlugin)
|
|
|
|
stanza = TestStanza()
|
|
self.assertTrue(stanza.match("foo"),
|
|
"Stanza did not match its own tag name.")
|
|
|
|
self.assertTrue(stanza.match("{foo}foo"),
|
|
"Stanza did not match its own namespaced name.")
|
|
|
|
stanza['bar'] = 'a'
|
|
self.assertTrue(stanza.match("foo@bar=a"),
|
|
"Stanza did not match its own name with attribute value check.")
|
|
|
|
stanza['baz'] = 'b'
|
|
self.assertTrue(stanza.match("foo@bar=a@baz=b"),
|
|
"Stanza did not match its own name with multiple attributes.")
|
|
|
|
stanza['qux'] = 'c'
|
|
self.assertTrue(stanza.match("foo/qux"),
|
|
"Stanza did not match with subelements.")
|
|
|
|
stanza['qux'] = ''
|
|
self.assertTrue(stanza.match("foo/qux") == False,
|
|
"Stanza matched missing subinterface element.")
|
|
|
|
self.assertTrue(stanza.match("foo/bar") == False,
|
|
"Stanza matched nonexistent element.")
|
|
|
|
stanza['plugin']['attrib'] = 'c'
|
|
self.assertTrue(stanza.match("foo/plugin@attrib=c"),
|
|
"Stanza did not match with plugin and attribute.")
|
|
|
|
self.assertTrue(stanza.match("foo/{http://test/slash/bar}plugin"),
|
|
"Stanza did not match with namespaced plugin.")
|
|
|
|
substanza = TestSubStanza()
|
|
substanza['attrib'] = 'd'
|
|
stanza.append(substanza)
|
|
self.assertTrue(stanza.match("foo/sub@attrib=d"),
|
|
"Stanza did not match with substanzas and attribute.")
|
|
|
|
self.assertTrue(stanza.match("foo/{baz}sub"),
|
|
"Stanza did not match with namespaced substanza.")
|
|
|
|
def testComparisons(self):
|
|
"""Test comparing ElementBase objects."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
stanza1 = TestStanza()
|
|
stanza1['bar'] = 'a'
|
|
|
|
self.assertTrue(stanza1,
|
|
"Stanza object does not evaluate to True")
|
|
|
|
stanza2 = TestStanza()
|
|
stanza2['baz'] = 'b'
|
|
|
|
self.assertTrue(stanza1 != stanza2,
|
|
"Different stanza objects incorrectly compared equal.")
|
|
|
|
stanza1['baz'] = 'b'
|
|
stanza2['bar'] = 'a'
|
|
|
|
self.assertTrue(stanza1 == stanza2,
|
|
"Equal stanzas incorrectly compared inequal.")
|
|
|
|
def testKeys(self):
|
|
"""Test extracting interface names from a stanza object."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
plugin_attrib = 'qux'
|
|
|
|
register_stanza_plugin(TestStanza, TestStanza)
|
|
|
|
stanza = TestStanza()
|
|
|
|
self.assertTrue(set(stanza.keys()) == {'lang', 'bar', 'baz'},
|
|
"Returned set of interface keys does not match expected.")
|
|
|
|
stanza.enable('qux')
|
|
|
|
self.assertTrue(set(stanza.keys()) == {'lang', 'bar', 'baz', 'qux'},
|
|
"Incorrect set of interface and plugin keys.")
|
|
|
|
def testGet(self):
|
|
"""Test accessing stanza interfaces using get()."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
stanza = TestStanza()
|
|
stanza['bar'] = 'a'
|
|
|
|
self.assertTrue(stanza.get('bar') == 'a',
|
|
"Incorrect value returned by stanza.get")
|
|
|
|
self.assertTrue(stanza.get('baz', 'b') == 'b',
|
|
"Incorrect default value returned by stanza.get")
|
|
|
|
def testSubStanzas(self):
|
|
"""Test manipulating substanzas of a stanza object."""
|
|
|
|
class TestSubStanza(ElementBase):
|
|
name = "foobar"
|
|
namespace = "foo"
|
|
interfaces = {'qux'}
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
register_stanza_plugin(TestStanza, TestSubStanza, iterable=True)
|
|
|
|
stanza = TestStanza()
|
|
substanza1 = TestSubStanza()
|
|
substanza2 = TestSubStanza()
|
|
substanza1['qux'] = 'a'
|
|
substanza2['qux'] = 'b'
|
|
|
|
# Test appending substanzas
|
|
self.assertTrue(len(stanza) == 0,
|
|
"Incorrect empty stanza size.")
|
|
|
|
stanza.append(substanza1)
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<foobar qux="a" />
|
|
</foo>
|
|
""", use_values=False)
|
|
self.assertTrue(len(stanza) == 1,
|
|
"Incorrect stanza size with 1 substanza.")
|
|
|
|
stanza.append(substanza2)
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<foobar qux="a" />
|
|
<foobar qux="b" />
|
|
</foo>
|
|
""", use_values=False)
|
|
self.assertTrue(len(stanza) == 2,
|
|
"Incorrect stanza size with 2 substanzas.")
|
|
|
|
# Test popping substanzas
|
|
stanza.pop(0)
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<foobar qux="b" />
|
|
</foo>
|
|
""", use_values=False)
|
|
|
|
# Test iterating over substanzas
|
|
stanza.append(substanza1)
|
|
results = []
|
|
for substanza in stanza:
|
|
results.append(substanza['qux'])
|
|
self.assertTrue(results == ['b', 'a'],
|
|
"Iteration over substanzas failed: %s." % str(results))
|
|
|
|
def testCopy(self):
|
|
"""Test copying stanza objects."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
stanza1 = TestStanza()
|
|
stanza1['bar'] = 'a'
|
|
|
|
stanza2 = stanza1.__copy__()
|
|
|
|
self.assertTrue(stanza1 == stanza2,
|
|
"Copied stanzas are not equal to each other.")
|
|
|
|
stanza1['baz'] = 'b'
|
|
self.assertTrue(stanza1 != stanza2,
|
|
"Divergent stanza copies incorrectly compared equal.")
|
|
|
|
def testExtension(self):
|
|
"""Testing using is_extension."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
class TestExtension(ElementBase):
|
|
name = 'extended'
|
|
namespace = 'foo'
|
|
plugin_attrib = name
|
|
interfaces = {name}
|
|
is_extension = True
|
|
|
|
def set_extended(self, value):
|
|
self.xml.text = value
|
|
|
|
def get_extended(self):
|
|
return self.xml.text
|
|
|
|
def del_extended(self):
|
|
self.parent().xml.remove(self.xml)
|
|
|
|
register_stanza_plugin(TestStanza, TestExtension)
|
|
|
|
stanza = TestStanza()
|
|
stanza['extended'] = 'testing'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<extended>testing</extended>
|
|
</foo>
|
|
""")
|
|
|
|
self.assertTrue(stanza['extended'] == 'testing',
|
|
"Could not retrieve stanza extension value.")
|
|
|
|
del stanza['extended']
|
|
self.check(stanza, """
|
|
<foo xmlns="foo" />
|
|
""")
|
|
|
|
def testOverrides(self):
|
|
"""Test using interface overrides."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar', 'baz'}
|
|
|
|
class TestOverride(ElementBase):
|
|
name = 'overrider'
|
|
namespace = 'foo'
|
|
plugin_attrib = name
|
|
interfaces = {'bar'}
|
|
overrides = ['set_bar']
|
|
|
|
def setup(self, xml):
|
|
# Don't create XML for the plugin
|
|
self.xml = ET.Element('')
|
|
|
|
def set_bar(self, value):
|
|
if not value.startswith('override-'):
|
|
self.parent()._set_attr('bar', 'override-%s' % value)
|
|
else:
|
|
self.parent()._set_attr('bar', value)
|
|
|
|
stanza = TestStanza()
|
|
stanza['bar'] = 'foo'
|
|
self.check(stanza, """
|
|
<foo xmlns="foo" bar="foo" />
|
|
""")
|
|
|
|
register_stanza_plugin(TestStanza, TestOverride, overrides=True)
|
|
|
|
stanza = TestStanza()
|
|
stanza['bar'] = 'foo'
|
|
self.check(stanza, """
|
|
<foo xmlns="foo" bar="override-foo" />
|
|
""")
|
|
|
|
def testBoolInterfaces(self):
|
|
"""Test using boolean interfaces."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = "foo"
|
|
namespace = "foo"
|
|
interfaces = {'bar'}
|
|
bool_interfaces = interfaces
|
|
|
|
stanza = TestStanza()
|
|
self.check(stanza, """
|
|
<foo xmlns="foo" />
|
|
""")
|
|
|
|
self.assertFalse(stanza['bar'],
|
|
"Returned True for missing bool interface element.")
|
|
|
|
stanza['bar'] = True
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<bar />
|
|
</foo>
|
|
""")
|
|
|
|
self.assertTrue(stanza['bar'],
|
|
"Returned False for present bool interface element.")
|
|
|
|
stanza['bar'] = False
|
|
self.check(stanza, """
|
|
<foo xmlns="foo" />
|
|
""")
|
|
|
|
def testGetMultiAttrib(self):
|
|
"""Test retrieving multi_attrib substanzas."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = 'foo'
|
|
namespace = 'foo'
|
|
interfaces = set()
|
|
|
|
class TestMultiStanza1(ElementBase):
|
|
name = 'bar'
|
|
namespace = 'bar'
|
|
plugin_attrib = name
|
|
plugin_multi_attrib = 'bars'
|
|
|
|
class TestMultiStanza2(ElementBase):
|
|
name = 'baz'
|
|
namespace = 'baz'
|
|
plugin_attrib = name
|
|
plugin_multi_attrib = 'bazs'
|
|
|
|
register_stanza_plugin(TestStanza, TestMultiStanza1, iterable=True)
|
|
register_stanza_plugin(TestStanza, TestMultiStanza2, iterable=True)
|
|
|
|
stanza = TestStanza()
|
|
stanza.append(TestMultiStanza1())
|
|
stanza.append(TestMultiStanza2())
|
|
stanza.append(TestMultiStanza1())
|
|
stanza.append(TestMultiStanza2())
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<bar xmlns="bar" />
|
|
<baz xmlns="baz" />
|
|
<bar xmlns="bar" />
|
|
<baz xmlns="baz" />
|
|
</foo>
|
|
""", use_values=False)
|
|
|
|
bars = stanza['bars']
|
|
bazs = stanza['bazs']
|
|
|
|
for bar in bars:
|
|
self.check(bar, """
|
|
<bar xmlns="bar" />
|
|
""")
|
|
|
|
for baz in bazs:
|
|
self.check(baz, """
|
|
<baz xmlns="baz" />
|
|
""")
|
|
|
|
self.assertEqual(len(bars), 2,
|
|
"Wrong number of <bar /> stanzas: %s" % len(bars))
|
|
self.assertEqual(len(bazs), 2,
|
|
"Wrong number of <baz /> stanzas: %s" % len(bazs))
|
|
|
|
def testSetMultiAttrib(self):
|
|
"""Test setting multi_attrib substanzas."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = 'foo'
|
|
namespace = 'foo'
|
|
interfaces = set()
|
|
|
|
class TestMultiStanza1(ElementBase):
|
|
name = 'bar'
|
|
namespace = 'bar'
|
|
plugin_attrib = name
|
|
plugin_multi_attrib = 'bars'
|
|
|
|
class TestMultiStanza2(ElementBase):
|
|
name = 'baz'
|
|
namespace = 'baz'
|
|
plugin_attrib = name
|
|
plugin_multi_attrib = 'bazs'
|
|
|
|
register_stanza_plugin(TestStanza, TestMultiStanza1, iterable=True)
|
|
register_stanza_plugin(TestStanza, TestMultiStanza2, iterable=True)
|
|
|
|
stanza = TestStanza()
|
|
stanza['bars'] = [TestMultiStanza1(), TestMultiStanza1()]
|
|
stanza['bazs'] = [TestMultiStanza2(), TestMultiStanza2()]
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<bar xmlns="bar" />
|
|
<bar xmlns="bar" />
|
|
<baz xmlns="baz" />
|
|
<baz xmlns="baz" />
|
|
</foo>
|
|
""", use_values=False)
|
|
|
|
self.assertEqual(len(stanza['substanzas']), 4,
|
|
"Wrong number of substanzas: %s" % len(stanza['substanzas']))
|
|
|
|
stanza['bars'] = [TestMultiStanza1()]
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<baz xmlns="baz" />
|
|
<baz xmlns="baz" />
|
|
<bar xmlns="bar" />
|
|
</foo>
|
|
""", use_values=False)
|
|
|
|
self.assertEqual(len(stanza['substanzas']), 3,
|
|
"Wrong number of substanzas: %s" % len(stanza['substanzas']))
|
|
|
|
|
|
def testDelMultiAttrib(self):
|
|
"""Test deleting multi_attrib substanzas."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = 'foo'
|
|
namespace = 'foo'
|
|
interfaces = set()
|
|
|
|
class TestMultiStanza1(ElementBase):
|
|
name = 'bar'
|
|
namespace = 'bar'
|
|
plugin_attrib = name
|
|
plugin_multi_attrib = 'bars'
|
|
|
|
class TestMultiStanza2(ElementBase):
|
|
name = 'baz'
|
|
namespace = 'baz'
|
|
plugin_attrib = name
|
|
plugin_multi_attrib = 'bazs'
|
|
|
|
register_stanza_plugin(TestStanza, TestMultiStanza1, iterable=True)
|
|
register_stanza_plugin(TestStanza, TestMultiStanza2, iterable=True)
|
|
|
|
stanza = TestStanza()
|
|
bars = [TestMultiStanza1(), TestMultiStanza1()]
|
|
bazs = [TestMultiStanza2(), TestMultiStanza2()]
|
|
|
|
stanza['bars'] = bars
|
|
stanza['bazs'] = bazs
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<bar xmlns="bar" />
|
|
<bar xmlns="bar" />
|
|
<baz xmlns="baz" />
|
|
<baz xmlns="baz" />
|
|
</foo>
|
|
""", use_values=False)
|
|
|
|
del stanza['bars']
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="foo">
|
|
<baz xmlns="baz" />
|
|
<baz xmlns="baz" />
|
|
</foo>
|
|
""", use_values=False)
|
|
|
|
self.assertEqual(len(stanza['substanzas']), 2,
|
|
"Wrong number of substanzas: %s" % len(stanza['substanzas']))
|
|
|
|
def testDefaultLang(self):
|
|
"""Test setting a normal subinterface when a default language is set"""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = 'foo'
|
|
namespace = 'test'
|
|
interfaces = {'test'}
|
|
sub_interfaces = interfaces
|
|
lang_interfaces = interfaces
|
|
|
|
stanza = TestStanza()
|
|
stanza['lang'] = 'sv'
|
|
stanza['test'] = 'hej'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test" xml:lang="sv">
|
|
<test>hej</test>
|
|
</foo>
|
|
""")
|
|
|
|
self.assertEqual(stanza['test'], 'hej',
|
|
"Incorrect subinterface value: %s" % stanza['test'])
|
|
|
|
self.assertEqual(stanza['test|sv'], 'hej',
|
|
"Incorrect subinterface value: %s" % stanza['test|sv'])
|
|
|
|
def testSpecifyLangWithDefault(self):
|
|
"""Test specifying various languages."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = 'foo'
|
|
namespace = 'test'
|
|
interfaces = {'test'}
|
|
sub_interfaces = interfaces
|
|
lang_interfaces = interfaces
|
|
|
|
stanza = TestStanza()
|
|
stanza['lang'] = 'sv'
|
|
stanza['test'] = 'hej'
|
|
stanza['test|en'] = 'hi'
|
|
stanza['test|es'] = 'hola'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test" xml:lang="sv">
|
|
<test>hej</test>
|
|
<test xml:lang="en">hi</test>
|
|
<test xml:lang="es">hola</test>
|
|
</foo>
|
|
""")
|
|
|
|
self.assertEqual(stanza['test'], 'hej',
|
|
"Incorrect subinterface value: %s" % stanza['test'])
|
|
|
|
self.assertEqual(stanza['test|sv'], 'hej',
|
|
"Incorrect subinterface value: %s" % stanza['test|sv'])
|
|
|
|
self.assertEqual(stanza['test|en'], 'hi',
|
|
"Incorrect subinterface value: %s" % stanza['test|en'])
|
|
|
|
self.assertEqual(stanza['test|es'], 'hola',
|
|
"Incorrect subinterface value: %s" % stanza['test|es'])
|
|
|
|
def testSpecifyLangWithNoDefault(self):
|
|
"""Test specifying various languages."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = 'foo'
|
|
namespace = 'test'
|
|
interfaces = {'test'}
|
|
sub_interfaces = interfaces
|
|
lang_interfaces = interfaces
|
|
|
|
stanza = TestStanza()
|
|
stanza['test'] = 'hej'
|
|
stanza['test|en'] = 'hi'
|
|
stanza['test|es'] = 'hola'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test">
|
|
<test>hej</test>
|
|
<test xml:lang="en">hi</test>
|
|
<test xml:lang="es">hola</test>
|
|
</foo>
|
|
""")
|
|
|
|
self.assertEqual(stanza['test'], 'hej',
|
|
"Incorrect subinterface value: %s" % stanza['test'])
|
|
|
|
self.assertEqual(stanza['test|en'], 'hi',
|
|
"Incorrect subinterface value: %s" % stanza['test|en'])
|
|
|
|
self.assertEqual(stanza['test|es'], 'hola',
|
|
"Incorrect subinterface value: %s" % stanza['test|es'])
|
|
|
|
def testModifyLangInterfaceWithDefault(self):
|
|
"""Test resetting an interface when a default lang is used."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = 'foo'
|
|
namespace = 'test'
|
|
interfaces = {'test'}
|
|
sub_interfaces = interfaces
|
|
lang_interfaces = interfaces
|
|
|
|
stanza = TestStanza()
|
|
stanza['lang'] = 'es'
|
|
stanza['test'] = 'hola'
|
|
stanza['test|en'] = 'hi'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test" xml:lang="es">
|
|
<test>hola</test>
|
|
<test xml:lang="en">hi</test>
|
|
</foo>
|
|
""")
|
|
|
|
stanza['test'] = 'adios'
|
|
stanza['test|en'] = 'bye'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test" xml:lang="es">
|
|
<test>adios</test>
|
|
<test xml:lang="en">bye</test>
|
|
</foo>
|
|
""")
|
|
|
|
self.assertEqual(stanza['test'], 'adios',
|
|
"Incorrect subinterface value: %s" % stanza['test'])
|
|
|
|
self.assertEqual(stanza['test|es'], 'adios',
|
|
"Incorrect subinterface value: %s" % stanza['test|es'])
|
|
|
|
self.assertEqual(stanza['test|en'], 'bye',
|
|
"Incorrect subinterface value: %s" % stanza['test|en'])
|
|
|
|
stanza['test|es'] = 'hola'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test" xml:lang="es">
|
|
<test>hola</test>
|
|
<test xml:lang="en">bye</test>
|
|
</foo>
|
|
""")
|
|
|
|
self.assertEqual(stanza['test'], 'hola',
|
|
"Incorrect subinterface value: %s" % stanza['test'])
|
|
|
|
self.assertEqual(stanza['test|es'], 'hola',
|
|
"Incorrect subinterface value: %s" % stanza['test|es'])
|
|
|
|
def testModifyLangInterfaceWithNoDefault(self):
|
|
"""Test resetting an interface when no default lang is used."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = 'foo'
|
|
namespace = 'test'
|
|
interfaces = {'test'}
|
|
sub_interfaces = interfaces
|
|
lang_interfaces = interfaces
|
|
|
|
stanza = TestStanza()
|
|
stanza['test'] = 'hola'
|
|
stanza['test|en'] = 'hi'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test">
|
|
<test>hola</test>
|
|
<test xml:lang="en">hi</test>
|
|
</foo>
|
|
""")
|
|
|
|
stanza['test'] = 'adios'
|
|
stanza['test|en'] = 'bye'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test">
|
|
<test>adios</test>
|
|
<test xml:lang="en">bye</test>
|
|
</foo>
|
|
""")
|
|
|
|
self.assertEqual(stanza['test'], 'adios',
|
|
"Incorrect subinterface value: %s" % stanza['test'])
|
|
|
|
self.assertEqual(stanza['test'], 'adios',
|
|
"Incorrect subinterface value: %s" % stanza['test|es'])
|
|
|
|
self.assertEqual(stanza['test|en'], 'bye',
|
|
"Incorrect subinterface value: %s" % stanza['test|en'])
|
|
|
|
def testDelInterfacesWithDefaultLang(self):
|
|
"""Test deleting interfaces with a default lang set."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = 'foo'
|
|
namespace = 'test'
|
|
interfaces = {'test'}
|
|
sub_interfaces = interfaces
|
|
lang_interfaces = interfaces
|
|
|
|
stanza = TestStanza()
|
|
stanza['lang'] = 'en'
|
|
stanza['test'] = 'hi'
|
|
stanza['test|no'] = 'hej'
|
|
stanza['test|fr'] = 'bonjour'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test" xml:lang="en">
|
|
<test>hi</test>
|
|
<test xml:lang="no">hej</test>
|
|
<test xml:lang="fr">bonjour</test>
|
|
</foo>
|
|
""")
|
|
|
|
del stanza['test']
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test" xml:lang="en">
|
|
<test xml:lang="no">hej</test>
|
|
<test xml:lang="fr">bonjour</test>
|
|
</foo>
|
|
""")
|
|
|
|
del stanza['test|no']
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test" xml:lang="en">
|
|
<test xml:lang="fr">bonjour</test>
|
|
</foo>
|
|
""")
|
|
|
|
def testDelInterfacesWithNoDefaultLang(self):
|
|
"""Test deleting interfaces with no default lang set."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = 'foo'
|
|
namespace = 'test'
|
|
interfaces = {'test'}
|
|
sub_interfaces = interfaces
|
|
lang_interfaces = interfaces
|
|
|
|
stanza = TestStanza()
|
|
stanza['test'] = 'hi'
|
|
stanza['test|no'] = 'hej'
|
|
stanza['test|fr'] = 'bonjour'
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test">
|
|
<test>hi</test>
|
|
<test xml:lang="no">hej</test>
|
|
<test xml:lang="fr">bonjour</test>
|
|
</foo>
|
|
""")
|
|
|
|
del stanza['test']
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test">
|
|
<test xml:lang="no">hej</test>
|
|
<test xml:lang="fr">bonjour</test>
|
|
</foo>
|
|
""")
|
|
|
|
del stanza['test|no']
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test">
|
|
<test xml:lang="fr">bonjour</test>
|
|
</foo>
|
|
""")
|
|
|
|
def testStarLang(self):
|
|
"""Test using interface|*."""
|
|
|
|
class TestStanza(ElementBase):
|
|
name = 'foo'
|
|
namespace = 'test'
|
|
interfaces = {'test'}
|
|
sub_interfaces = interfaces
|
|
lang_interfaces = interfaces
|
|
|
|
data = {}
|
|
data['en'] = 'hi'
|
|
data['fr'] = 'bonjour'
|
|
data['no'] = 'hej'
|
|
|
|
stanza = TestStanza()
|
|
stanza['test|*'] = data
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test">
|
|
<test xml:lang="en">hi</test>
|
|
<test xml:lang="fr">bonjour</test>
|
|
<test xml:lang="no">hej</test>
|
|
</foo>
|
|
""")
|
|
|
|
data2 = stanza['test|*']
|
|
|
|
self.assertEqual(data, data2,
|
|
"Did not extract expected language data: %s" % data2)
|
|
|
|
del stanza['test|*']
|
|
|
|
self.check(stanza, """
|
|
<foo xmlns="test" />
|
|
""")
|
|
|
|
|
|
suite = unittest.TestLoader().loadTestsFromTestCase(TestElementBase)
|