def get_object_as_xml_cloth(inst, cls=None, no_namespace=False, encoding='utf8'): """Returns an ElementTree representation of a :class:`spyne.model.complex.ComplexModel` subclass. :param inst: The instance of the class to be serialized. :param cls: The class to be serialized. Optional. :param root_tag_name: The root tag string to use. Defaults to the output of ``value.__class__.get_type_name_ns()``. :param no_namespace: When true, namespace information is discarded. """ if cls is None: cls = inst.__class__ if cls.get_namespace() is None and no_namespace is None: no_namespace = True if no_namespace is None: no_namespace = False ostr = BytesIO() xml_cloth = XmlCloth(use_ns=(not no_namespace)) ctx = FakeContext() with etree.xmlfile(ostr, encoding=encoding) as xf: ctx.outprot_ctx.doctype_written = False ctx.protocol.prot_stack = tlist([], ProtocolMixin) tn = cls.get_type_name() ret = xml_cloth.subserialize(ctx, cls, inst, xf, tn) assert not isgenerator(ret) return ostr.getvalue()
class TestXmlClothToParent(unittest.TestCase): def setUp(self): self.ctx = FakeContext() self.stream = BytesIO() logging.basicConfig(level=logging.DEBUG) def _run(self, inst, cls=None): if cls is None: cls = inst.__class__ with etree.xmlfile(self.stream) as parent: XmlCloth().subserialize(self.ctx, cls, inst, parent, name=cls.__name__) elt = etree.fromstring(self.stream.getvalue()) print(etree.tostring(elt, pretty_print=True)) return elt def test_simple(self): v = 'punk.' elt = self._run(v, Unicode) assert elt.text == v def test_complex_primitive(self): class SomeObject(ComplexModel): s = Unicode v = 'punk.' elt = self._run(SomeObject(s=v)) assert elt[0].text == v def test_complex_inheritance(self): class A(ComplexModel): i = Integer class B(A): s = Unicode i = 42 s = 'punk.' elt = self._run(B(i=i, s=s)) # order is important assert len(elt) == 2 assert elt[0].text == str(i) assert elt[1].text == s
def chart(ctx, typename): """Return a sparkline chart of the given type.""" data = ctx.descriptor.service_class.history[typename] height = 20.0 scale = height / max(data) im = Image.new("RGB", (len(data), int(height)), 'white') draw = ImageDraw.Draw(im) draw.line([(i, int(height - (v * scale))) for i, v in enumerate(data)], fill="#009900") del draw f = BytesIO() im.save(f, "PNG") result = f.getvalue() ctx.out_protocol = HttpRpc() ctx.transport.resp_headers["Content-Type"] = "image/png" return [result]
class TestXmlCloth(unittest.TestCase): def setUp(self): self.ctx = FakeContext() self.stream = BytesIO() logging.basicConfig(level=logging.DEBUG) def _run(self, inst, spid=None, cloth=None): cls = inst.__class__ if cloth is None: assert spid is not None cloth = etree.fromstring("""<a><b spyne_id="%s"></b></a>""" % spid) else: assert spid is None with etree.xmlfile(self.stream) as parent: XmlCloth(cloth=cloth).subserialize(self.ctx, cls, inst, parent) elt = etree.fromstring(self.stream.getvalue()) print etree.tostring(elt, pretty_print=True) return elt def test_simple_value(self): class SomeObject(ComplexModel): s = Unicode v = 'punk.' elt = self._run(SomeObject(s=v), spid='s') assert elt[0].text == v def test_simple_empty(self): class SomeObject(ComplexModel): s = Unicode elt = self._run(SomeObject(), spid='s') assert len(elt) == 0 # FIXME: just fix it def _test_simple_empty_nonoptional(self): class SomeObject(ComplexModel): s = Unicode(min_occurs=1) elt = self._run(SomeObject(), spid='s') assert elt[0].text is None # FIXME: just fix it def _test_simple_empty_nonoptional_clear(self): class SomeObject(ComplexModel): s = Unicode(min_occurs=1) cloth = etree.fromstring("""<a><b spyne_id="s">oi punk!</b></a>""") elt = self._run(SomeObject(), cloth=cloth) assert elt[0].text is None def test_simple_value_xmlattribute(self): v = 'punk.' class SomeObject(ComplexModel): s = XmlAttribute(Unicode(min_occurs=1)) cloth = etree.fromstring("""<a></a>""") elt = self._run(SomeObject(s=v), cloth=cloth) assert elt.attrib['s'] == v def test_array(self): v = range(3) class SomeObject(ComplexModel): s = Array(Integer) cloth = E.a( E.b( E.c(spyne_id="integer"), spyne_id="s", ) ) elt = self._run(SomeObject(s=v), cloth=cloth) assert elt.xpath('//c/text()') == [str(i) for i in v] def test_array_empty(self): class SomeObject(ComplexModel): s = Array(Integer) elt_str = '<a><b spyne_id="s"><c spyne_id="integer"></c></b></a>' cloth = etree.fromstring(elt_str) elt = self._run(SomeObject(), cloth=cloth) assert elt.xpath('//c') == [] # FIXME: just fix it def _test_array_empty_nonoptional(self): class SomeObject(ComplexModel): s = Array(Integer(min_occurs=1)) elt_str = '<a><b spyne_id="s"><c spyne_id="integer"></c></b></a>' cloth = etree.fromstring(elt_str) elt = self._run(SomeObject(), cloth=cloth) assert elt.xpath('//c') == [cloth[0][0]] def test_simple_two_tags(self): class SomeObject(ComplexModel): s = Unicode i = Integer v = SomeObject(s='s', i=5) cloth = E.a( E.b1(), E.b2( E.c1(spyne_id="s"), E.c2(), ), E.e( E.g1(), E.g2(spyne_id="i"), E.g3(), ), ) elt = self._run(v, cloth=cloth) print etree.tostring(elt, pretty_print=True) assert elt[0].tag == 'b1' assert elt[1].tag == 'b2' assert elt[1][0].tag == 'c1' assert elt[1][0].text == 's' assert elt[1][1].tag == 'c2' assert elt[2].tag == 'e' assert elt[2][0].tag == 'g1' assert elt[2][1].tag == 'g2' assert elt[2][1].text == '5' assert elt[2][2].tag == 'g3'
class TestXmlCloth(unittest.TestCase): def setUp(self): self.ctx = FakeContext() self.stream = BytesIO() logging.basicConfig(level=logging.DEBUG) def _run(self, inst, spid=None, cloth=None): cls = inst.__class__ if cloth is None: assert spid is not None cloth = etree.fromstring("""<a><b spyne_id="%s"></b></a>""" % spid) else: assert spid is None with etree.xmlfile(self.stream) as parent: XmlCloth(cloth=cloth).set_identifier_prefix('spyne_') \ .subserialize(self.ctx, cls, inst, parent) elt = etree.fromstring(self.stream.getvalue()) print(etree.tostring(elt, pretty_print=True)) return elt def test_simple_value(self): class SomeObject(ComplexModel): s = Unicode v = 'punk.' elt = self._run(SomeObject(s=v), spid='s') assert elt[0].text == v def test_simple_empty(self): class SomeObject(ComplexModel): s = Unicode elt = self._run(SomeObject(), spid='s') assert len(elt) == 0 # FIXME: just fix it def _test_simple_empty_nonoptional(self): class SomeObject(ComplexModel): s = Unicode(min_occurs=1) elt = self._run(SomeObject(), spid='s') assert elt[0].text is None # FIXME: just fix it def _test_simple_empty_nonoptional_clear(self): class SomeObject(ComplexModel): s = Unicode(min_occurs=1) cloth = etree.fromstring("""<a><b spyne_id="s">oi punk!</b></a>""") elt = self._run(SomeObject(), cloth=cloth) assert elt[0].text is None def test_xml_data_tag(self): class SomeObject(ComplexModel): d = XmlData(Unicode) cloth = etree.fromstring('<a><spyne_data spyne_id="d"/></a>') elt = self._run(SomeObject(d='data'), cloth=cloth) assert elt.text == 'data' def test_xml_data_attr(self): class SomeObject(ComplexModel): d = XmlData(Unicode) cloth = etree.fromstring('<a spyne_data="d"></a>') elt = self._run(SomeObject(d='data'), cloth=cloth) assert elt.text == 'data' def test_xml_data_attr(self): class SomeObject(ComplexModel): d = XmlData(Unicode) cloth = etree.fromstring('<a spyne_data="d"></a>') elt = self._run(SomeObject(d='data'), cloth=cloth) assert elt.text == 'data' def test_xml_data_attr_undesignated(self): class SomeObject(ComplexModel): d = Unicode cloth = etree.fromstring('<a spyne_data="d"></a>') elt = self._run(SomeObject(d='data'), cloth=cloth) assert elt.text == 'data' def test_simple_value_xmlattribute(self): v = 'punk.' class SomeObject(ComplexModel): s = XmlAttribute(Unicode(min_occurs=1)) cloth = etree.fromstring("""<a></a>""") elt = self._run(SomeObject(s=v), cloth=cloth) assert elt.attrib['s'] == v def test_simple_value_xmlattribute_subname(self): v = 'punk.' class SomeObject(ComplexModel): s = XmlAttribute(Unicode(min_occurs=1, sub_name='foo')) cloth = etree.fromstring("""<a></a>""") elt = self._run(SomeObject(s=v), cloth=cloth) assert elt.attrib['foo'] == v def test_simple_value_xmlattribute_non_immediate(self): v = 'punk.' class SomeObject(ComplexModel): s = XmlAttribute(Unicode(min_occurs=1, sub_name='foo')) cloth = etree.fromstring("""<a><b spyne_attr="s"/></a>""") elt = self._run(SomeObject(s=v), cloth=cloth) assert elt.attrib['foo'] == v assert elt[0].attrib['foo'] == v def test_simple_value_xmlattribute_non_immediate_non_designated(self): v = 'punk.' class SomeObject(ComplexModel): s = Unicode(min_occurs=1, sub_name='foo') cloth = etree.fromstring("""<a><b spyne_attr="s"/></a>""") elt = self._run(SomeObject(s=v), cloth=cloth) assert not 'foo' in elt.attrib assert elt[0].attrib['foo'] == v def test_non_tagbag(self): cloth = E.a( E.b( E.c( E.d( spyne_id="i", ), spyne_id="c", ), spyne_id="i", ), spyne_tagbag='', ) class C2(ComplexModel): i = Integer class C1(ComplexModel): i = Integer c = C2 elt = self._run(C1(i=1, c=C2(i=2)), cloth=cloth) assert elt.xpath('//b/text()') == ['1'] # no order guarantee is given assert set(elt.xpath('//d/text()')) == set(['1', '2']) def test_array(self): v = range(3) class SomeObject(ComplexModel): s = Array(Integer) cloth = E.a( E.b( E.c(spyne_id="integer"), spyne_id="s", ) ) elt = self._run(SomeObject(s=v), cloth=cloth) assert elt.xpath('//c/text()') == [str(i) for i in v] def test_array_empty(self): class SomeObject(ComplexModel): s = Array(Integer) elt_str = '<a><b spyne_id="s"><c spyne_id="integer"></c></b></a>' cloth = etree.fromstring(elt_str) elt = self._run(SomeObject(), cloth=cloth) assert elt.xpath('//c') == [] # FIXME: just fix it def _test_array_empty_nonoptional(self): class SomeObject(ComplexModel): s = Array(Integer(min_occurs=1)) elt_str = '<a><b spyne_id="s"><c spyne_id="integer"></c></b></a>' cloth = etree.fromstring(elt_str) elt = self._run(SomeObject(), cloth=cloth) assert elt.xpath('//c') == [cloth[0][0]] def test_simple_two_tags(self): class SomeObject(ComplexModel): s = Unicode i = Integer v = SomeObject(s='s', i=5) cloth = E.a( E.b1(), E.b2( E.c1(spyne_id="s"), E.c2(), ), E.e( E.g1(), E.g2(spyne_id="i"), E.g3(), ), ) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == 'b1' assert elt[1].tag == 'b2' assert elt[1][0].tag == 'c1' assert elt[1][0].text == 's' assert elt[1][1].tag == 'c2' assert elt[2].tag == 'e' assert elt[2][0].tag == 'g1' assert elt[2][1].tag == 'g2' assert elt[2][1].text == '5' assert elt[2][2].tag == 'g3' def test_sibling_order(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s='s') cloth = E.a( E.b1(), E.b2( E.c0(), E.c1(), E.c2(spyne_id="s"), E.c3(), E.c4(), ), ) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == 'b1' assert elt[1].tag == 'b2' assert elt[1][0].tag == 'c0' assert elt[1][1].tag == 'c1' assert elt[1][2].tag == 'c2' assert elt[1][2].text == 's' assert elt[1][3].tag == 'c3' assert elt[1][4].tag == 'c4' def test_parent_text(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s='s') cloth = E.a( "text 0", E.b1(spyne_id="s"), ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt.tag == 'a' assert elt.text == 'text 0' assert elt[0].tag == 'b1' assert elt[0].text == 's' def test_anc_text(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s='s') cloth = E.a( E.b1( "text 1", E.c1(spyne_id="s"), ) ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == 'b1' assert elt[0].text == 'text 1' assert elt[0][0].tag == 'c1' assert elt[0][0].text == 's' def test_prevsibl_tail(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s='s') cloth = E.a( E.b1( E.c1(), "text 2", E.c2(spyne_id="s"), ) ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == 'b1' assert elt[0][0].tag == 'c1' assert elt[0][0].tail == 'text 2' assert elt[0][1].text == 's' def test_sibling_tail_close(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s='s') cloth = E.a( E.b0(spyne_id="s"), "text 3", ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == 'b0' assert elt[0].text == 's' assert elt[0].tail == 'text 3' def test_sibling_tail_close_sibling(self): class SomeObject(ComplexModel): s = Unicode i = Integer v = SomeObject(s='s', i=5) cloth = E.a( E.b0(spyne_id="s"), "text 3", E.b1(spyne_id="i"), ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == 'b0' assert elt[0].text == 's' assert elt[0].tail == 'text 3' def test_sibling_tail_close_anc(self): class SomeObject(ComplexModel): s = Unicode i = Integer v = SomeObject(s='s', i=5) cloth = E.a( E.b0(), "text 0", E.b1( E.c0(spyne_id="s"), "text 1", E.c1(), "text 2", ), "text 3", E.b2( E.c1(spyne_id="i"), "text 4", ) ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt.xpath('/a/b1/c0')[0].tail == 'text 1' assert elt.xpath('/a/b1/c1')[0].tail == 'text 2' assert elt.xpath('/a/b2/c1')[0].tail == 'text 4' def test_nested_conflicts(self): class SomeObject(ComplexModel): s = Unicode i = Integer c = SelfReference v = SomeObject(s='x', i=1, c=SomeObject(s='y', i=2)) cloth = E.a( E.b0(), "text 0", E.b1( E.c0(spyne_id="s"), "text 1", E.c1( E.d0(spyne_id="s"), E.d1(spyne_id="i"), spyne_id="c", ), "text 2", ), "text 3", E.b2( E.c2(spyne_id="i"), "text 4", ) ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt.xpath('/a/b1/c0')[0].text == str(v.s) assert elt.xpath('/a/b1/c1/d0')[0].text == str(v.c.s) assert elt.xpath('/a/b1/c1/d1')[0].text == str(v.c.i) assert elt.xpath('/a/b2/c2')[0].text == str(v.i)
class TestXmlCloth(unittest.TestCase): def setUp(self): self.ctx = FakeContext() self.stream = BytesIO() logging.basicConfig(level=logging.DEBUG) def _run(self, inst, spid=None, cloth=None): cls = inst.__class__ if cloth is None: assert spid is not None cloth = etree.fromstring("""<a><b spyne_id="%s"></b></a>""" % spid) else: assert spid is None with etree.xmlfile(self.stream) as parent: XmlCloth.ID_ATTR_NAME = 'spyne_id' XmlCloth.TAGBAG_ATTR_NAME = 'spyne_tagbag' XmlCloth(cloth=cloth).subserialize(self.ctx, cls, inst, parent) elt = etree.fromstring(self.stream.getvalue()) print(etree.tostring(elt, pretty_print=True)) return elt def test_simple_value(self): class SomeObject(ComplexModel): s = Unicode v = 'punk.' elt = self._run(SomeObject(s=v), spid='s') assert elt[0].text == v def test_simple_empty(self): class SomeObject(ComplexModel): s = Unicode elt = self._run(SomeObject(), spid='s') assert len(elt) == 0 # FIXME: just fix it def _test_simple_empty_nonoptional(self): class SomeObject(ComplexModel): s = Unicode(min_occurs=1) elt = self._run(SomeObject(), spid='s') assert elt[0].text is None # FIXME: just fix it def _test_simple_empty_nonoptional_clear(self): class SomeObject(ComplexModel): s = Unicode(min_occurs=1) cloth = etree.fromstring("""<a><b spyne_id="s">oi punk!</b></a>""") elt = self._run(SomeObject(), cloth=cloth) assert elt[0].text is None def test_simple_value_xmlattribute(self): v = 'punk.' class SomeObject(ComplexModel): s = XmlAttribute(Unicode(min_occurs=1)) cloth = etree.fromstring("""<a></a>""") elt = self._run(SomeObject(s=v), cloth=cloth) assert elt.attrib['s'] == v def test_non_tagbag(self): cloth = E.a( E.b( E.c( E.d( spyne_id="i", ), spyne_id="c", ), spyne_id="i", ), spyne_tagbag='', ) class C2(ComplexModel): i = Integer class C1(ComplexModel): i = Integer c = C2 elt = self._run(C1(i=1, c=C2(i=2)), cloth=cloth) assert elt.xpath('//b/text()') == ['1'] # no order guarantee is given assert set(elt.xpath('//d/text()')) == set(['1', '2']) def test_array(self): v = range(3) class SomeObject(ComplexModel): s = Array(Integer) cloth = E.a( E.b( E.c(spyne_id="integer"), spyne_id="s", ) ) elt = self._run(SomeObject(s=v), cloth=cloth) assert elt.xpath('//c/text()') == [str(i) for i in v] def test_array_empty(self): class SomeObject(ComplexModel): s = Array(Integer) elt_str = '<a><b spyne_id="s"><c spyne_id="integer"></c></b></a>' cloth = etree.fromstring(elt_str) elt = self._run(SomeObject(), cloth=cloth) assert elt.xpath('//c') == [] # FIXME: just fix it def _test_array_empty_nonoptional(self): class SomeObject(ComplexModel): s = Array(Integer(min_occurs=1)) elt_str = '<a><b spyne_id="s"><c spyne_id="integer"></c></b></a>' cloth = etree.fromstring(elt_str) elt = self._run(SomeObject(), cloth=cloth) assert elt.xpath('//c') == [cloth[0][0]] def test_simple_two_tags(self): class SomeObject(ComplexModel): s = Unicode i = Integer v = SomeObject(s='s', i=5) cloth = E.a( E.b1(), E.b2( E.c1(spyne_id="s"), E.c2(), ), E.e( E.g1(), E.g2(spyne_id="i"), E.g3(), ), ) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == 'b1' assert elt[1].tag == 'b2' assert elt[1][0].tag == 'c1' assert elt[1][0].text == 's' assert elt[1][1].tag == 'c2' assert elt[2].tag == 'e' assert elt[2][0].tag == 'g1' assert elt[2][1].tag == 'g2' assert elt[2][1].text == '5' assert elt[2][2].tag == 'g3' def test_sibling_order(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s='s') cloth = E.a( E.b1(), E.b2( E.c0(), E.c1(), E.c2(spyne_id="s"), E.c3(), E.c4(), ), ) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == 'b1' assert elt[1].tag == 'b2' assert elt[1][0].tag == 'c0' assert elt[1][1].tag == 'c1' assert elt[1][2].tag == 'c2' assert elt[1][2].text == 's' assert elt[1][3].tag == 'c3' assert elt[1][4].tag == 'c4' def test_parent_text(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s='s') cloth = E.a( "text 0", E.b1(spyne_id="s"), ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt.tag == 'a' assert elt.text == 'text 0' assert elt[0].tag == 'b1' assert elt[0].text == 's' def test_anc_text(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s='s') cloth = E.a( E.b1( "text 1", E.c1(spyne_id="s"), ) ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == 'b1' assert elt[0].text == 'text 1' assert elt[0][0].tag == 'c1' assert elt[0][0].text == 's' def test_prevsibl_tail(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s='s') cloth = E.a( E.b1( E.c1(), "text 2", E.c2(spyne_id="s"), ) ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == 'b1' assert elt[0][0].tag == 'c1' assert elt[0][0].tail == 'text 2' assert elt[0][1].text == 's' def test_sibling_tail_close(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s='s') cloth = E.a( E.b0(spyne_id="s"), "text 3", ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == 'b0' assert elt[0].text == 's' assert elt[0].tail == 'text 3' def test_sibling_tail_close_sibling(self): class SomeObject(ComplexModel): s = Unicode i = Integer v = SomeObject(s='s', i=5) cloth = E.a( E.b0(spyne_id="s"), "text 3", E.b1(spyne_id="i"), ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == 'b0' assert elt[0].text == 's' assert elt[0].tail == 'text 3' def test_sibling_tail_close_anc(self): class SomeObject(ComplexModel): s = Unicode i = Integer v = SomeObject(s='s', i=5) cloth = E.a( E.b0(), "text 0", E.b1( E.c0(spyne_id="s"), "text 1", E.c1(), "text 2", ), "text 3", E.b2( E.c1(spyne_id="i"), "text 4", ) ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt.xpath('/a/b1/c0')[0].tail == 'text 1' assert elt.xpath('/a/b1/c1')[0].tail == 'text 2' assert elt.xpath('/a/b2/c1')[0].tail == 'text 4' def test_nested_conflicts(self): class SomeObject(ComplexModel): s = Unicode i = Integer c = SelfReference v = SomeObject(s='x', i=1, c=SomeObject(s='y', i=2)) cloth = E.a( E.b0(), "text 0", E.b1( E.c0(spyne_id="s"), "text 1", E.c1( E.d0(spyne_id="s"), E.d1(spyne_id="i"), spyne_id="c", ), "text 2", ), "text 3", E.b2( E.c2(spyne_id="i"), "text 4", ) ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt.xpath('/a/b1/c0')[0].text == str(v.s) assert elt.xpath('/a/b1/c1/d0')[0].text == str(v.c.s) assert elt.xpath('/a/b1/c1/d1')[0].text == str(v.c.i) assert elt.xpath('/a/b2/c2')[0].text == str(v.i)
class TestXmlCloth(unittest.TestCase): def setUp(self): self.ctx = FakeContext() self.stream = BytesIO() logging.basicConfig(level=logging.DEBUG) def _run(self, inst, spid=None, cloth=None): cls = inst.__class__ if cloth is None: assert spid is not None cloth = etree.fromstring("""<a><b spyne_id="%s"></b></a>""" % spid) else: assert spid is None with etree.xmlfile(self.stream) as parent: XmlCloth(cloth=cloth).set_identifier_prefix("spyne_").subserialize(self.ctx, cls, inst, parent) elt = etree.fromstring(self.stream.getvalue()) print(etree.tostring(elt, pretty_print=True)) return elt def test_simple_value(self): class SomeObject(ComplexModel): s = Unicode v = "punk." elt = self._run(SomeObject(s=v), spid="s") assert elt[0].text == v def test_simple_empty(self): class SomeObject(ComplexModel): s = Unicode elt = self._run(SomeObject(), spid="s") assert len(elt) == 0 # FIXME: just fix it def _test_simple_empty_nonoptional(self): class SomeObject(ComplexModel): s = Unicode(min_occurs=1) elt = self._run(SomeObject(), spid="s") assert elt[0].text is None # FIXME: just fix it def _test_simple_empty_nonoptional_clear(self): class SomeObject(ComplexModel): s = Unicode(min_occurs=1) cloth = etree.fromstring("""<a><b spyne_id="s">oi punk!</b></a>""") elt = self._run(SomeObject(), cloth=cloth) assert elt[0].text is None def test_xml_data_tag(self): class SomeObject(ComplexModel): d = XmlData(Unicode) cloth = etree.fromstring('<a><spyne_data spyne_id="d"/></a>') elt = self._run(SomeObject(d="data"), cloth=cloth) assert elt.text == "data" def test_xml_data_attr(self): class SomeObject(ComplexModel): d = XmlData(Unicode) cloth = etree.fromstring('<a spyne_data="d"></a>') elt = self._run(SomeObject(d="data"), cloth=cloth) assert elt.text == "data" def test_xml_data_attr(self): class SomeObject(ComplexModel): d = XmlData(Unicode) cloth = etree.fromstring('<a spyne_data="d"></a>') elt = self._run(SomeObject(d="data"), cloth=cloth) assert elt.text == "data" def test_xml_data_attr_undesignated(self): class SomeObject(ComplexModel): d = Unicode cloth = etree.fromstring('<a spyne_data="d"></a>') elt = self._run(SomeObject(d="data"), cloth=cloth) assert elt.text == "data" def test_simple_value_xmlattribute(self): v = "punk." class SomeObject(ComplexModel): s = XmlAttribute(Unicode(min_occurs=1)) cloth = etree.fromstring("""<a></a>""") elt = self._run(SomeObject(s=v), cloth=cloth) assert elt.attrib["s"] == v def test_simple_value_xmlattribute_subname(self): v = "punk." class SomeObject(ComplexModel): s = XmlAttribute(Unicode(min_occurs=1, sub_name="foo")) cloth = etree.fromstring("""<a></a>""") elt = self._run(SomeObject(s=v), cloth=cloth) assert elt.attrib["foo"] == v def test_simple_value_xmlattribute_non_immediate(self): v = "punk." class SomeObject(ComplexModel): s = XmlAttribute(Unicode(min_occurs=1, sub_name="foo")) cloth = etree.fromstring("""<a><b spyne_attr="s"/></a>""") elt = self._run(SomeObject(s=v), cloth=cloth) assert elt.attrib["foo"] == v assert elt[0].attrib["foo"] == v def test_simple_value_xmlattribute_non_immediate_non_designated(self): v = "punk." class SomeObject(ComplexModel): s = Unicode(min_occurs=1, sub_name="foo") cloth = etree.fromstring("""<a><b spyne_attr="s"/></a>""") elt = self._run(SomeObject(s=v), cloth=cloth) assert not "foo" in elt.attrib assert elt[0].attrib["foo"] == v def test_non_tagbag(self): cloth = E.a(E.b(E.c(E.d(spyne_id="i"), spyne_id="c"), spyne_id="i"), spyne_tagbag="") class C2(ComplexModel): i = Integer class C1(ComplexModel): i = Integer c = C2 elt = self._run(C1(i=1, c=C2(i=2)), cloth=cloth) assert elt.xpath("//b/text()") == ["1"] # no order guarantee is given assert set(elt.xpath("//d/text()")) == set(["1", "2"]) def test_array(self): v = range(3) class SomeObject(ComplexModel): s = Array(Integer) cloth = E.a(E.b(E.c(spyne_id="integer"), spyne_id="s")) elt = self._run(SomeObject(s=v), cloth=cloth) assert elt.xpath("//c/text()") == [str(i) for i in v] def test_array_empty(self): class SomeObject(ComplexModel): s = Array(Integer) elt_str = '<a><b spyne_id="s"><c spyne_id="integer"></c></b></a>' cloth = etree.fromstring(elt_str) elt = self._run(SomeObject(), cloth=cloth) assert elt.xpath("//c") == [] # FIXME: just fix it def _test_array_empty_nonoptional(self): class SomeObject(ComplexModel): s = Array(Integer(min_occurs=1)) elt_str = '<a><b spyne_id="s"><c spyne_id="integer"></c></b></a>' cloth = etree.fromstring(elt_str) elt = self._run(SomeObject(), cloth=cloth) assert elt.xpath("//c") == [cloth[0][0]] def test_simple_two_tags(self): class SomeObject(ComplexModel): s = Unicode i = Integer v = SomeObject(s="s", i=5) cloth = E.a(E.b1(), E.b2(E.c1(spyne_id="s"), E.c2()), E.e(E.g1(), E.g2(spyne_id="i"), E.g3())) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == "b1" assert elt[1].tag == "b2" assert elt[1][0].tag == "c1" assert elt[1][0].text == "s" assert elt[1][1].tag == "c2" assert elt[2].tag == "e" assert elt[2][0].tag == "g1" assert elt[2][1].tag == "g2" assert elt[2][1].text == "5" assert elt[2][2].tag == "g3" def test_sibling_order(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s="s") cloth = E.a(E.b1(), E.b2(E.c0(), E.c1(), E.c2(spyne_id="s"), E.c3(), E.c4())) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == "b1" assert elt[1].tag == "b2" assert elt[1][0].tag == "c0" assert elt[1][1].tag == "c1" assert elt[1][2].tag == "c2" assert elt[1][2].text == "s" assert elt[1][3].tag == "c3" assert elt[1][4].tag == "c4" def test_parent_text(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s="s") cloth = E.a("text 0", E.b1(spyne_id="s")) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt.tag == "a" assert elt.text == "text 0" assert elt[0].tag == "b1" assert elt[0].text == "s" def test_anc_text(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s="s") cloth = E.a(E.b1("text 1", E.c1(spyne_id="s"))) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == "b1" assert elt[0].text == "text 1" assert elt[0][0].tag == "c1" assert elt[0][0].text == "s" def test_prevsibl_tail(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s="s") cloth = E.a(E.b1(E.c1(), "text 2", E.c2(spyne_id="s"))) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == "b1" assert elt[0][0].tag == "c1" assert elt[0][0].tail == "text 2" assert elt[0][1].text == "s" def test_sibling_tail_close(self): class SomeObject(ComplexModel): s = Unicode v = SomeObject(s="s") cloth = E.a(E.b0(spyne_id="s"), "text 3") print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == "b0" assert elt[0].text == "s" assert elt[0].tail == "text 3" def test_sibling_tail_close_sibling(self): class SomeObject(ComplexModel): s = Unicode i = Integer v = SomeObject(s="s", i=5) cloth = E.a(E.b0(spyne_id="s"), "text 3", E.b1(spyne_id="i")) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt[0].tag == "b0" assert elt[0].text == "s" assert elt[0].tail == "text 3" def test_sibling_tail_close_anc(self): class SomeObject(ComplexModel): s = Unicode i = Integer v = SomeObject(s="s", i=5) cloth = E.a( E.b0(), "text 0", E.b1(E.c0(spyne_id="s"), "text 1", E.c1(), "text 2"), "text 3", E.b2(E.c1(spyne_id="i"), "text 4"), ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt.xpath("/a/b1/c0")[0].tail == "text 1" assert elt.xpath("/a/b1/c1")[0].tail == "text 2" assert elt.xpath("/a/b2/c1")[0].tail == "text 4" def test_nested_conflicts(self): class SomeObject(ComplexModel): s = Unicode i = Integer c = SelfReference v = SomeObject(s="x", i=1, c=SomeObject(s="y", i=2)) cloth = E.a( E.b0(), "text 0", E.b1(E.c0(spyne_id="s"), "text 1", E.c1(E.d0(spyne_id="s"), E.d1(spyne_id="i"), spyne_id="c"), "text 2"), "text 3", E.b2(E.c2(spyne_id="i"), "text 4"), ) print(etree.tostring(cloth, pretty_print=True)) elt = self._run(v, cloth=cloth) print(etree.tostring(elt, pretty_print=True)) assert elt.xpath("/a/b1/c0")[0].text == str(v.s) assert elt.xpath("/a/b1/c1/d0")[0].text == str(v.c.s) assert elt.xpath("/a/b1/c1/d1")[0].text == str(v.c.i) assert elt.xpath("/a/b2/c2")[0].text == str(v.i)