class XmlSerializerTests(TestCase): def setUp(self): super(XmlSerializerTests, self).setUp() self.serializer = XmlSerializer(pretty_print=True) self.namespaces = Namespaces() self.books = Books( book=[ BookForm( id="bk001", author="Hightower, Kim", title="The First Book", genre="Fiction", price=44.95, pub_date="2000-10-01", review="An amazing story of nothing.", ), BookForm( id="bk002", author="Nagata, Suanne", title="Becoming Somebody", genre="Biography", review="A masterpiece of the fine art of gossiping.", ), ] ) def test_render(self): actual = self.serializer.render(self.books) expected = ( "<?xml version='1.0' encoding='UTF-8'?>\n" '<ns0:books xmlns:ns0="urn:books">\n' ' <book id="bk001" lang="en">\n' " <author>Hightower, Kim</author>\n" " <title>The First Book</title>\n" " <genre>Fiction</genre>\n" " <price>44.95</price>\n" " <pub_date>2000-10-01</pub_date>\n" " <review>An amazing story of nothing.</review>\n" " </book>\n" ' <book id="bk002" lang="en">\n' " <author>Nagata, Suanne</author>\n" " <title>Becoming Somebody</title>\n" " <genre>Biography</genre>\n" " <review>A masterpiece of the fine art of gossiping.</review>\n" " </book>\n" "</ns0:books>\n" ) self.assertEqual(expected, actual) def test_render_with_provided_namespaces(self): self.namespaces.add("urn:books", "burn") actual = self.serializer.render(self.books, self.namespaces) expected = ( "<?xml version='1.0' encoding='UTF-8'?>\n" '<burn:books xmlns:burn="urn:books">\n' ' <book id="bk001" lang="en">\n' " <author>Hightower, Kim</author>\n" " <title>The First Book</title>\n" " <genre>Fiction</genre>\n" " <price>44.95</price>\n" " <pub_date>2000-10-01</pub_date>\n" " <review>An amazing story of nothing.</review>\n" " </book>\n" ' <book id="bk002" lang="en">\n' " <author>Nagata, Suanne</author>\n" " <title>Becoming Somebody</title>\n" " <genre>Biography</genre>\n" " <review>A masterpiece of the fine art of gossiping.</review>\n" " </book>\n" "</burn:books>\n" ) self.assertEqual(expected, actual) def test_render_no_dataclass(self): with self.assertRaises(XmlContextError) as cm: self.serializer.render(self) self.assertEqual( f"Object {self.__class__} is not a dataclass.", str(cm.exception) ) @mock.patch.object(SerializeUtils, "set_nil_attribute") @mock.patch.object(SerializeUtils, "set_text") @mock.patch.object(SerializeUtils, "set_attributes") @mock.patch.object(SerializeUtils, "set_attribute") @mock.patch.object(XmlSerializer, "render_sub_node") @mock.patch.object(XmlSerializer, "next_value") def test_render_node( self, mock_next_value, mock_render_sub_node, mock_set_attribute, mock_set_attributes, mock_set_text, mock_set_nil_attribute, ): root = Element("root") prod_meta = self.serializer.context.build(ProductType) size_meta = self.serializer.context.build(SizeType) obj = ProductType() attribute = prod_meta.find_var("effDate") attributes = prod_meta.find_var("{!}other_attributes") text = replace(size_meta.find_var("value"), qname=QName("foo", "bar")) sub_node = prod_meta.find_var("name") mock_next_value.return_value = [ (attribute, None), (attribute, 1), (attributes, dict(a=1)), (text, "txt"), (sub_node, 1), (sub_node, [2, 3]), ] self.serializer.render_node(root, obj, self.namespaces) self.assertEqual({"ns0": "foo"}, self.namespaces.ns_map) mock_set_attribute.assert_called_once_with( root, attribute.qname, 1, self.namespaces ) mock_set_attributes.assert_called_once_with(root, dict(a=1), self.namespaces) mock_set_text.assert_called_once_with(root, "txt", self.namespaces) mock_render_sub_node.assert_has_calls( [ mock.call(root, 1, sub_node, self.namespaces), mock.call(root, 2, sub_node, self.namespaces), mock.call(root, 3, sub_node, self.namespaces), ] ) mock_set_nil_attribute.assert_called_once_with(root, False, self.namespaces) def test_render_node_without_dataclass(self): root = Element("root") self.serializer.render_node(root, 1, self.namespaces) self.assertEqual("1", root.text) @mock.patch.object(XmlSerializer, "render_sub_node") def test_render_sub_nodes(self, mock_render_sub_node): root = Element("root") meta = self.serializer.context.build(ProductType) var = meta.find_var("number") self.serializer.render_sub_nodes(root, [1, 2, 3], var, self.namespaces) self.assertEqual(3, mock_render_sub_node.call_count) mock_render_sub_node.assert_has_calls( [ mock.call(root, 1, var, self.namespaces), mock.call(root, 2, var, self.namespaces), mock.call(root, 3, var, self.namespaces), ] ) @mock.patch.object(XmlSerializer, "render_wildcard_node") def test_render_sub_node_with_generic_object(self, mock_render_wildcard_node): root = Element("root") value = AnyElement() meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_sub_node(root, value, var, self.namespaces) self.assertEqual(1, mock_render_wildcard_node.call_count) mock_render_wildcard_node.assert_called_once_with( root, value, var, self.namespaces ) @mock.patch.object(XmlSerializer, "render_element_node") def test_render_sub_node_with_xml_element(self, mock_render_element_node): root = Element("root") value = 1 meta = self.serializer.context.build(ProductType) var = meta.find_var("number") self.serializer.render_sub_node(root, value, var, self.namespaces) self.assertEqual(1, mock_render_element_node.call_count) mock_render_element_node.assert_called_once_with( root, value, var, self.namespaces ) @mock.patch.object(XmlSerializer, "render_element_node") def test_render_sub_node_with_dataclass_object(self, mock_render_element_node): root = Element("root") value = SizeType() meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_sub_node(root, value, var, self.namespaces) self.assertEqual(1, mock_render_element_node.call_count) mock_render_element_node.assert_called_once_with( root, value, var, self.namespaces ) @mock.patch.object(SerializeUtils, "set_tail") @mock.patch.object(SerializeUtils, "set_text") def test_render_sub_node_with_primitive_value_and_not_xml_element( self, mock_set_text, mock_set_tail ): root = Element("root") value = 1 meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_sub_node(root, value, var, self.namespaces) self.assertEqual(1, mock_set_text.call_count) mock_set_text.assert_called_once_with(root, value, self.namespaces) root.text = "foo" self.serializer.render_sub_node(root, value, var, self.namespaces) self.assertEqual(1, mock_set_tail.call_count) mock_set_tail.assert_called_once_with(root, value, self.namespaces) @mock.patch.object(SerializeUtils, "set_nil_attribute") @mock.patch.object(XmlSerializer, "set_xsi_type") @mock.patch.object(XmlSerializer, "render_node") def test_render_element_node( self, mock_render_node, mock_set_xsi_type, mock_set_nil_attribute ): root = Element("root") value = SizeType() meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_element_node(root, value, var, self.namespaces) child = root[0] mock_render_node.assert_called_once_with(child, value, self.namespaces) mock_set_xsi_type.assert_called_once_with(child, value, var, self.namespaces) mock_set_nil_attribute.assert_called_once_with( child, var.nillable, self.namespaces ) self.assertEqual(var.qname, child.tag) self.assertEqual( {"ns0": "http://www.w3.org/1999/xhtml"}, self.namespaces.ns_map ) @mock.patch.object(SerializeUtils, "set_nil_attribute") @mock.patch.object(XmlSerializer, "render_node") def test_render_element_node_with_specific_qname( self, mock_render_node, mock_set_nil_attribute ): root = Element("root") value = SizeType() value.qname = "foo" meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_element_node(root, value, var, self.namespaces) child = root[0] mock_render_node.assert_called_once_with(child, value, self.namespaces) mock_set_nil_attribute.assert_called_once_with( child, var.nillable, self.namespaces ) self.assertEqual("foo", child.tag) self.assertEqual(0, len(self.namespaces.ns_map)) @mock.patch.object(XmlSerializer, "render_sub_node") @mock.patch.object(SerializeUtils, "set_nil_attribute") @mock.patch.object(SerializeUtils, "set_attributes") @mock.patch.object(SerializeUtils, "set_tail") @mock.patch.object(SerializeUtils, "set_text") def test_render_wildcard_node( self, mock_set_text, mock_set_tail, mock_set_attributes, mock_set_nil_attribute, mock_render_sub_node, ): root = Element("root") value = AnyElement( text="foo", tail="bar", attributes=dict(a=1), children=[AnyElement(), AnyElement()], ns_map={"foo": "bar"}, qname="foo", ) meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_wildcard_node(root, value, var, self.namespaces) child = root[0] self.assertEqual({"foo": "bar"}, self.namespaces.ns_map) self.assertEqual(value.qname, child.tag) mock_set_text.assert_called_once_with(child, value.text, self.namespaces) mock_set_tail.assert_called_once_with(child, value.tail, self.namespaces) mock_set_attributes.assert_called_once_with( child, value.attributes, self.namespaces ) mock_render_sub_node.assert_has_calls( [ mock.call(child, value.children[0], var, self.namespaces), mock.call(child, value.children[1], var, self.namespaces), ] ) mock_set_nil_attribute.assert_called_once_with( child, var.nillable, self.namespaces ) @mock.patch.object(XmlSerializer, "render_sub_node") @mock.patch.object(SerializeUtils, "set_nil_attribute") @mock.patch.object(SerializeUtils, "set_attributes") @mock.patch.object(SerializeUtils, "set_tail") @mock.patch.object(SerializeUtils, "set_text") def test_render_wildcard_node_without_qname( self, mock_set_text, mock_set_tail, mock_set_attributes, mock_set_nil_attribute, mock_render_sub_node, ): root = Element("root") value = AnyElement( text="foo", tail="bar", attributes=dict(a=1), children=[AnyElement()] ) meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_wildcard_node(root, value, var, self.namespaces) self.assertEqual(0, len(self.namespaces.ns_map)) self.assertEqual(0, len(root)) mock_set_text.assert_called_once_with(root, value.text, self.namespaces) mock_set_tail.assert_called_once_with(root, value.tail, self.namespaces) mock_set_attributes.assert_called_once_with( root, value.attributes, self.namespaces ) mock_render_sub_node.assert_called_once_with( root, value.children[0], var, self.namespaces ) mock_set_nil_attribute.assert_called_once_with( root, var.nillable, self.namespaces ) def test_set_xsi_type_with_non_dataclass(self): elem = Element("foo") value = 1 meta = self.serializer.context.build(ProductType) var = meta.find_var("number") self.serializer.set_xsi_type(elem, value, var, self.namespaces) self.assertNotIn(QNames.XSI_TYPE, elem.attrib) def test_set_xsi_type_when_value_type_matches_var_clazz(self): elem = Element("foo") value = SizeType() meta = self.serializer.context.build(ProductType) var = meta.find_var("size") self.serializer.set_xsi_type(elem, value, var, self.namespaces) self.assertNotIn(QNames.XSI_TYPE, elem.attrib) def test_set_xsi_type_when_value_is_not_derived_from_var_clazz(self): elem = Element("foo") value = ColorType() meta = self.serializer.context.build(ProductType) var = meta.find_var("size") with self.assertRaises(SerializerError) as cm: self.serializer.set_xsi_type(elem, value, var, self.namespaces) self.assertEqual("ColorType is not derived from SizeType", str(cm.exception)) @mock.patch.object(XmlContext, "is_derived", return_value=True) def test_set_xsi_type_when_value_is_derived_from_var_clazz(self, *args): elem = Element("foo") value = Items() meta = self.serializer.context.build(ProductType) items_meta = self.serializer.context.build(Items) var = meta.find_var("size") self.serializer.set_xsi_type(elem, value, var, self.namespaces) self.assertEqual(items_meta.source_qname, elem.attrib[QNames.XSI_TYPE]) def test_next_value(self): @dataclass class A: x0: Optional[int] = field(default=None) x1: List[int] = field( default_factory=list, metadata=dict(type="Element", sequential=True) ) x2: List[int] = field( default_factory=list, metadata=dict(type="Element", sequential=True) ) x3: Optional[int] = field(default=None) obj = A(x0=1, x1=[2, 3, 4], x2=[6, 7], x3=8) meta = self.serializer.context.build(A) x0 = meta.find_var("x0") x1 = meta.find_var("x1") x2 = meta.find_var("x2") x3 = meta.find_var("x3") actual = self.serializer.next_value(meta, obj) expected = [ (x0, 1), (x1, 2), (x2, 6), (x1, 3), (x2, 7), (x1, 4), (x3, 8), ] self.assertIsInstance(actual, Iterator) self.assertEqual(expected, list(actual))
class XmlSerializerTests(TestCase): def setUp(self) -> None: self.serializer = XmlSerializer() def test_write_object_with_derived_element(self): book = BookForm(id="123") obj = DerivedElement(qname="item", value=book) result = self.serializer.write_object(obj) expected = [ (XmlWriterEvent.START, "item"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.ATTR, QNames.XSI_TYPE, "{urn:books}BookForm"), (XmlWriterEvent.END, "item"), ] self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_dataclass(self): book = BookForm(id="123", title="Misterioso: A Crime Novel", price=19.5) result = self.serializer.write_object(book) expected = [ (XmlWriterEvent.START, "BookForm"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.START, "title"), (XmlWriterEvent.DATA, "Misterioso: A Crime Novel"), (XmlWriterEvent.END, "title"), (XmlWriterEvent.START, "price"), (XmlWriterEvent.DATA, "19.5"), (XmlWriterEvent.END, "price"), (XmlWriterEvent.END, "BookForm"), ] self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_dataclass_can_overwrite_params(self): book = BookForm(id="123", title="Misterioso: A Crime Novel", price=19.5) result = self.serializer.write_dataclass(book, "xsdata", "book", True, "foo:book") expected = [ (XmlWriterEvent.START, "book"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.ATTR, QNames.XSI_TYPE, "foo:book"), (XmlWriterEvent.ATTR, QNames.XSI_NIL, "true"), (XmlWriterEvent.START, "title"), (XmlWriterEvent.DATA, "Misterioso: A Crime Novel"), (XmlWriterEvent.END, "title"), (XmlWriterEvent.START, "price"), (XmlWriterEvent.DATA, "19.5"), (XmlWriterEvent.END, "price"), (XmlWriterEvent.END, "book"), ] self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_dataclass_with_no_dataclass(self): with self.assertRaises(XmlContextError) as cm: next(self.serializer.write_dataclass(1)) self.assertEqual("Object <class 'int'> is not a dataclass.", str(cm.exception)) def test_write_mixed_content(self): var = XmlVar(wildcard=True, qname="a", name="a", mixed=True) book = BookForm(id="123") ebook = DerivedElement("ebook", BookForm(id="123")) value = ["text", AnyElement(qname="br"), book, ebook, "tail"] result = self.serializer.write_value(value, var, "xsdata") expected = [ (XmlWriterEvent.DATA, "text"), (XmlWriterEvent.START, "br"), (XmlWriterEvent.DATA, None), (XmlWriterEvent.END, "br"), (XmlWriterEvent.START, "{xsdata}BookForm"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.END, "{xsdata}BookForm"), (XmlWriterEvent.START, "ebook"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.END, "ebook"), (XmlWriterEvent.DATA, "tail"), ] self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_data(self): var = XmlVar(text=True, qname="a", name="a") expected = [(XmlWriterEvent.DATA, "123")] result = self.serializer.write_value("123", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_tokens(self): var = XmlVar(element=True, qname="a", name="a", tokens=True) result = self.serializer.write_value([], var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(0, len(list(result))) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, ["1", QName("{a}b"), "3"]), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value([1, QName("{a}b"), 3], var, "xsdata") self.assertEqual(expected, list(result)) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, ["1", "2", "3"]), (XmlWriterEvent.END, "a"), (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, ["4", "5", "6"]), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value([[1, 2, 3], [4, 5, 6]], var, "xsdata") self.assertEqual(expected, list(result)) var = XmlVar(element=True, qname="a", name="a", tokens=True, nillable=True) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, QNames.XSI_NIL, "true"), (XmlWriterEvent.DATA, []), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value([], var, "xsdata") self.assertEqual(expected, list(result)) def test_write_any_type_with_primitive(self): var = XmlVar(wildcard=True, qname="a", name="a") expected = [(XmlWriterEvent.DATA, "str")] result = self.serializer.write_value("str", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_any_type_with_primitive_element(self): var = XmlVar(element=True, qname="a", name="a", types=[object]) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "str"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value("str", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_any_type_with_any_element(self): var = XmlVar(wildcard=True, qname="a", name="a") value = AnyElement( qname="a", text="b", tail="c", attributes={ "d": 1, "e": 2 }, children=[AnyElement(text="g"), "h"], ) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, "d", 1), (XmlWriterEvent.ATTR, "e", 2), (XmlWriterEvent.DATA, "b"), (XmlWriterEvent.DATA, "g"), (XmlWriterEvent.DATA, "h"), (XmlWriterEvent.END, "a"), (XmlWriterEvent.DATA, "c"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_any_type_with_derived_element_primitive(self): var = XmlVar(wildcard=True, qname="a", name="a") value = DerivedElement(qname="a", value=1) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, QNames.XSI_TYPE, QName(str(DataType.SHORT))), (XmlWriterEvent.DATA, 1), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_any_type_with_derived_element_dataclass(self): var = XmlVar(wildcard=True, qname="a", name="a") value = DerivedElement(qname="a", value=BookForm(title="def"), substituted=True) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.ATTR, QNames.XSI_TYPE, QName("{urn:books}BookForm")), (XmlWriterEvent.START, "title"), (XmlWriterEvent.DATA, "def"), (XmlWriterEvent.END, "title"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_xsi_type(self): var = XmlVar(element=True, qname="a", name="a", dataclass=True, types=[BookForm]) value = BookForm(id="123") expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_xsi_type_with_derived_class(self): var = XmlVar(element=True, qname="a", name="a", dataclass=True, types=[BookForm]) ebook = make_dataclass("eBook", [], bases=(BookForm, )) value = ebook(id="123") expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.ATTR, QNames.XSI_TYPE, QName("eBook")), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_xsi_type_with_illegal_derived_class(self): var = XmlVar(element=True, qname="a", name="a", dataclass=True, types=[BookForm]) ebook = make_dataclass("eBook", []) value = ebook() result = self.serializer.write_value(value, var, "xsdata") with self.assertRaises(SerializerError) as cm: list(result) self.assertEqual("eBook is not derived from BookForm", str(cm.exception)) def test_write_element(self): var = XmlVar(element=True, qname="a", name="a") expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "123"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value("123", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_element_with_nillable_true(self): var = XmlVar(element=True, qname="a", name="a", nillable=True) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, QNames.XSI_NIL, "true"), (XmlWriterEvent.DATA, "123"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value("123", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_element_with_any_type_var(self): var = XmlVar(element=True, qname="a", name="a", types=[object], any_type=True) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, QNames.XSI_TYPE, QName(str(DataType.SHORT))), (XmlWriterEvent.DATA, "123"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(123, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_element_with_any_type_var_ignore_xs_string(self): var = XmlVar(element=True, qname="a", name="a", types=[object], any_type=True) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, ""), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value("", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "123"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value("123", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_choice_with_derived_primitive_value(self): var = XmlVar( elements=True, name="compound", qname="compound", choices=[XmlVar(element=True, qname="a", name="a", types=[int])], ) value = DerivedElement(qname="a", value=1) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "1"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_choice_with_derived_dataclass(self): var = XmlVar( elements=True, name="compound", qname="compound", choices=[XmlVar(element=True, qname="a", name="a", types=[A])], ) value = DerivedElement(qname="a", value=A("foo")) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, "a0", "foo"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_choice_with_generic_object(self): var = XmlVar( elements=True, name="compound", qname="compound", choices=[XmlVar(element=True, qname="a", name="a", types=[int])], ) value = AnyElement(qname="a", text="1") expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "1"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_choice_with_raw_value(self): var = XmlVar( elements=True, name="compound", qname="compound", choices=[ XmlVar(element=True, qname="a", name="a", types=[int]), XmlVar(element=True, qname="b", name="b", types=[int], tokens=True), ], ) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "1"), (XmlWriterEvent.END, "a"), (XmlWriterEvent.START, "b"), (XmlWriterEvent.DATA, ["1", "2"]), (XmlWriterEvent.END, "b"), ] result = self.serializer.write_value([1, [1, 2]], var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_choice_when_no_matching_choice_exists(self): var = XmlVar( elements=True, name="compound", qname="compound", choices=[XmlVar(element=True, qname="a", name="a", types=[float])], ) with self.assertRaises(SerializerError) as cm: result = self.serializer.write_value(1, var, "xsdata") next(result) msg = "XmlElements undefined choice: `compound` for `<class 'int'>`" self.assertEqual(msg, str(cm.exception)) def test_write_value_with_list_value(self): var = XmlVar(element=True, qname="a", name="a", list_element=True) value = [True, False] expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "true"), (XmlWriterEvent.END, "a"), (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "false"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_next_value(self): obj = A(x0=1, x1=[2, 3, 4], x2=[6, 7], x3=[9]) meta = self.serializer.context.build(A) x0 = meta.find_var("x0") x1 = meta.find_var("x1") x2 = meta.find_var("x2") x3 = meta.find_var("x3") actual = self.serializer.next_value(obj, meta) expected = [ (x0, 1), (x1, 2), (x2, 6), (x3, 9), (x1, 3), (x2, 7), (x1, 4), ] self.assertIsInstance(actual, Generator) self.assertEqual(expected, list(actual)) def test_next_attribute(self): obj = A(a0="foo", a1={"b": "c", "d": "e"}) meta = self.serializer.context.build(A) actual = self.serializer.next_attribute(obj, meta, False, None) expected = [ ("a0", "foo"), ("b", "c"), ("d", "e"), ] self.assertIsInstance(actual, Generator) self.assertEqual(expected, list(actual)) actual = self.serializer.next_attribute(obj, meta, True, "xs:bool") expected.extend([ (QNames.XSI_TYPE, "xs:bool"), (QNames.XSI_NIL, "true"), ]) self.assertEqual(expected, list(actual)) def test_render_mixed_content(self): @dataclass class Span: class Meta: name = "span" content: str @dataclass class Example: class Meta: name = "p" content: List[object] = field( default_factory=list, metadata=dict( type="Wildcard", namespace="##any", mixed=True, min_occurs=0, max_occurs=9223372036854775807, ), ) obj = Example() obj.content.append(AnyElement(qname="b", text="Mr.")) obj.content.append(Span("chris")) obj.content.append("!") self.serializer.pretty_print = False result = self.serializer.render(obj).splitlines() self.assertEqual("<p><b>Mr.</b><span>chris</span>!</p>", result[1]) obj = Example() obj.content.append("Hi ") obj.content.append(AnyElement(qname="b", text="Mr.")) obj.content.append(Span("chris")) obj.content.append("!") result = self.serializer.render(obj).splitlines() self.assertEqual("<p>Hi <b>Mr.</b><span>chris</span>!</p>", result[1])