예제 #1
0
def validate_bindings(schema: Path, clazz: Type, output_format: str):
    __tracebackhide__ = True

    chapter = schema.stem.replace("chapter", "")

    sample = here.joinpath(f"samples/chapter{chapter}.xml")
    output_xml = here.joinpath(f"output/chapter{chapter}.xsdata.xml")
    output_json = here.joinpath(f"output/chapter{chapter}.xsdata.json")

    context = XmlContext(class_type=output_format)
    obj = XmlParser(context=context).from_path(sample, clazz)
    config = SerializerConfig(pretty_print=True)

    actual_json = JsonSerializer(context=context, config=config).render(obj)
    actual_xml = XmlSerializer(context=context, config=config).render(obj)

    if output_json.exists() and chapter != "13":
        assert output_json.read_text() == actual_json
        assert obj == JsonParser(context=context).from_string(
            actual_json, clazz)
    else:
        output_json.write_text(actual_json, encoding="utf-8")

    if output_xml.exists():
        assert output_xml.read_text() == actual_xml
    else:
        output_xml.write_text(actual_xml, encoding="utf-8")

    validator = etree.XMLSchema(etree.parse(str(schema)))
    validator.assertValid(etree.fromstring(actual_xml.encode()))
예제 #2
0
def dumps(root_element, *, format=False) -> str:
    """Serialize a SDFormat object to an XML string.

    Parameters
    ----------
    root_element : object
        An instance of ``skbot.ignition.models.vXX.Sdf``. XX represents the SDFormat
        version and can be any version currently supported by scikit-bot.
    format : bool
        If true, add indentation and linebreaks to the output to increase human
        readability. If false (default) the entire XML will appear as a single
        line with no spaces between elements.

    Returns
    -------
    sdformat_string : str
        A string containing SDFormat XML representing the given input.

    Examples
    --------
    .. minigallery:: skbot.ignition.sdformat.dumps

    """
    serializer = XmlSerializer(config=SerializerConfig(pretty_print=format))

    return serializer.render(root_element)
예제 #3
0
    def test_render_with_provided_namespaces(self):
        serializer = XmlSerializer(pretty_print=True)
        namespaces = Namespaces()
        namespaces.add("urn:books", "burn")
        actual = serializer.render(self.books, 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)
예제 #4
0
    def __init__(self, *, config: Configuration) -> None:
        self.config = config

        self.serializer = XmlSerializer(config=SerializerConfig(
            pretty_print=False))
        self.parser = XmlParser(context=XmlContext())
        self.requests: WeakValueDictionary[str,
                                           Future] = WeakValueDictionary({})
        super().__init__()
예제 #5
0
def serialize(obj: object, pretty_print: bool = False) -> str:
    ns_map = __get_ns_map(obj)
    schema_location = __get_ns_schema_location(obj)
    config = SerializerConfig(xml_version='1.0',
                              encoding='UTF-8',
                              schema_location=schema_location,
                              pretty_print=pretty_print)
    serializer = XmlSerializer(config=config)

    return serializer.render(obj, ns_map=ns_map)
예제 #6
0
 def write(cls, output: TextIO, obj: "GeneratorConfig"):
     ctx = XmlContext(
         element_name_generator=text.pascal_case,
         attribute_name_generator=text.camel_case,
     )
     config = SerializerConfig(pretty_print=True)
     serializer = XmlSerializer(context=ctx,
                                config=config,
                                writer=XmlEventWriter)
     serializer.write(output,
                      obj,
                      ns_map={None: "http://pypi.org/project/xsdata"})
예제 #7
0
def writer(xrnsfile, song):

    xrns = XrnsSerializer()
    xml_song = xrns.render(song)

    config = SerializerConfig(pretty_print=True,
                              encoding="UTF-8",
                              xml_version="1.0")
    serializer = XmlSerializer(config=config)  # , writer=XmlEventWriter)

    rendered = serializer.render(xml_song)

    with zipfile.ZipFile(xrnsfile, mode="w") as zf:
        zf.writestr("Song.xml", rendered)
예제 #8
0
    def test_client_with_soap_fault(self, mock_most):
        url = "http://localhost:9999/ws/hello"
        request = fixtures_dir.joinpath("hello/HelloRQ.xml").read_text()
        response = fixtures_dir.joinpath(
            "hello/HelloRS_SoapFault.xml").read_bytes()
        headers = {"content-type": "text/xml"}
        mock_most.return_value = response

        config = Config.from_service(HelloGetHelloAsString)
        serializer = XmlSerializer(config=SerializerConfig(pretty_print=True))
        client = Client(config=config, serializer=serializer)
        result = client.send(
            {"body": {
                "get_hello_as_string": {
                    "arg0": "chris"
                }
            }})

        self.assertIsInstance(result, HelloGetHelloAsString.output)

        fault = HelloGetHelloAsStringOutput.Body.Fault(
            faultcode="S:Server",
            faultstring="foobar",
            detail=HelloGetHelloAsStringOutput.Body.Fault.Detail(
                hello_error=HelloError(message="foobar")),
        )
        self.assertEqual(fault, result.body.fault)

        mock_most.assert_called_once_with(url, data=request, headers=headers)
예제 #9
0
    def test_client(self, mock_most):
        url = "http://localhost:9999/ws/hello"
        request = fixtures_dir.joinpath("hello/HelloRQ.xml").read_text()
        response = fixtures_dir.joinpath("hello/HelloRS.xml").read_bytes()
        headers = {"content-type": "text/xml"}
        mock_most.return_value = response

        config = Config.from_service(HelloGetHelloAsString)
        serializer = XmlSerializer(config=SerializerConfig(pretty_print=True))
        client = Client(config=config, serializer=serializer)
        result = client.send(
            {"body": {
                "get_hello_as_string": {
                    "arg0": "chris"
                }
            }})

        self.assertIsInstance(result, HelloGetHelloAsString.output)

        body = HelloGetHelloAsStringOutput.Body(
            get_hello_as_string_response=GetHelloAsStringResponse(
                return_value="Hello chris"))
        self.assertEqual(body, result.body)

        mock_most.assert_called_once_with(url, data=request, headers=headers)
예제 #10
0
def assert_xml_bindings(
    context: XmlContext,
    obj: Any,
    ns_map: Dict,
    schema_path: Path,
    instance_path: Path,
    save_path: Optional[Path],
    version: str,
):
    __tracebackhide__ = True

    schema_validator = get_validator(schema_path, version)
    if schema_validator is None:
        pytest.skip("Schema validator failed on parsing definition")

    try:
        xsdata_xml = XmlSerializer(context=context, config=config).render(obj, ns_map)
        if save_path:
            json_document = JsonSerializer(context=context, config=config).render(obj)
            save_path.write_text(xsdata_xml)
            save_path.with_suffix(".json").write_text(json_document)
        return assert_valid(schema_validator, xsdata_xml)
    except Exception as e:
        try:
            original_tree = etree.parse(str(instance_path))
            assert_valid(schema_validator, original_tree)
        except Exception:
            pytest.skip("Original instance failed to validate!")

        raise e
예제 #11
0
def write_file_from_xml(xml_file_path: pathlib.Path,
                        serialize_clazz: Optional[Type[T]]):
    """
    Method to write serialized XML data to a file.
    :param xml_file_path: A pathlib.path path object that the data will write to.
    :param serialize_clazz: A class Object.
    :return: N/A
    """
    serializer = XmlSerializer(
        config=SerializerConfig(pretty_print=True,
                                encoding="UTF-8",
                                xml_version="1.1",
                                xml_declaration=False,
                                schema_location="resources/xmltv.xsd",
                                no_namespace_schema_location=None))

    with xml_file_path.open("w") as data:
        serializer.write(data, serialize_clazz)
예제 #12
0
 def test_live(self):
     config = Config.from_service(HelloGetHelloAsString)
     serializer = XmlSerializer(config=SerializerConfig(pretty_print=True))
     client = Client(config=config, serializer=serializer)
     result = client.send(
         {"body": {
             "get_hello_as_string": {
                 "arg0": "chris"
             }
         }})
     print(result)
예제 #13
0
def validate_bindings(schema: Path, clazz: Type):
    __tracebackhide__ = True

    obj = XmlParser().from_path(schema.with_suffix(".xml"), clazz)
    actual = JsonSerializer(indent=4).render(obj)

    expected = schema.with_suffix(".json")
    if expected.exists():
        assert expected.read_text() == actual
        assert obj == JsonParser().from_string(actual, clazz)
    else:
        expected.write_text(actual)

    xml = XmlSerializer(pretty_print=True).render(obj)

    validator = etree.XMLSchema(etree.parse(str(schema)))
    assert validator.validate(etree.fromstring(
        xml.encode())), validator.error_log

    expected.with_suffix(".xsdata.xml").write_text(xml)
예제 #14
0
 def setUp(self):
     super().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.",
         ),
     ])
예제 #15
0
def test_xml_documents():
    filepath = fixtures_dir.joinpath("artists")
    package = "tests.fixtures.artists"
    runner = CliRunner()
    result = runner.invoke(cli, [str(filepath), "--package", package])

    if result.exception:
        raise result.exception

    clazz = load_class(result.output, "Metadata")

    parser = XmlParser()
    serializer = XmlSerializer(writer=XmlEventWriter)
    serializer.config.pretty_print = True
    serializer.config.xml_declaration = False
    ns_map = {None: "http://musicbrainz.org/ns/mmd-2.0#"}

    for i in range(1, 4):
        ap = filepath.joinpath(f"art00{i}.xml")
        obj = parser.from_path(ap, clazz)
        actual = serializer.render(obj, ns_map)

        assert ap.read_bytes().splitlines() == actual.encode().splitlines()
예제 #16
0
    def test_client(self, mock_most):
        url = "http://www.dneonline.com/calculator.asmx"
        request = fixtures_dir.joinpath("calculator/AddRQ.xml").read_text()
        response = fixtures_dir.joinpath("calculator/AddRS.xml").read_bytes()
        headers = {"content-type": "text/xml", "SOAPAction": "http://tempuri.org/Add"}
        mock_most.return_value = response

        config = Config.from_service(CalculatorSoapAdd)
        serializer = XmlSerializer(config=SerializerConfig(pretty_print=True))
        client = Client(config=config, serializer=serializer)
        result = client.send({"Body": {"Add": {"intA": 1, "intB": 3}}})

        self.assertIsInstance(result, CalculatorSoapAddOutput)

        mock_most.assert_called_once_with(url, data=request, headers=headers)
예제 #17
0
class LxmlEventWriterTests(TestCase):
    def setUp(self):
        config = SerializerConfig(pretty_print=True)
        self.serializer = XmlSerializer(config=config, writer=LxmlEventWriter)

    def test_render(self):
        actual = self.serializer.render(books)
        expected = fixtures_dir.joinpath("books/books_auto_ns.xml").read_text()

        self.assertEqual(expected, actual)

    def test_render_with_provided_namespaces(self):
        actual = self.serializer.render(books, {"brk": "urn:books"})
        expected = fixtures_dir.joinpath("books/books.xml").read_text()

        self.assertEqual(expected, actual)

    def test_render_with_default_namespace_prefix(self):
        actual = self.serializer.render(books, {None: "urn:books"})
        expected = fixtures_dir.joinpath(
            "books/books_default_ns.xml").read_text()

        xml_declaration, actual = actual.split("\n", 1)
        _, expected = expected.split("\n", 1)

        self.assertEqual(expected, actual)

    def test_encoding(self):
        self.serializer.config.encoding = "US-ASCII"
        self.serializer.config.xml_version = "1.1"
        actual = self.serializer.render(books)
        xml_declaration, _ = actual.split("\n", 1)

        self.assertEqual('<?xml version="1.1" encoding="US-ASCII"?>',
                         xml_declaration)

    def test_declaration_disabled(self):
        self.serializer.config.xml_declaration = False
        actual = self.serializer.render(books, {None: "urn:books"})
        expected = fixtures_dir.joinpath(
            "books/books_default_ns.xml").read_text()
        xml_declaration, expected = expected.split("\n", 1)

        self.assertEqual(expected, actual)

    def test_pretty_print_false(self):
        self.serializer.config.pretty_print = False
        actual = self.serializer.render(books)
        expected = fixtures_dir.joinpath("books/books_auto_ns.xml").read_text()

        _, actual = actual.split("\n", 1)
        _, expected = expected.split("\n", 1)
        self.assertEqual(expected.replace("  ", "").replace("\n", ""), actual)
예제 #18
0
    def __init_serializer(
        self, schema_location=None, no_namespace_schema_location=None
    ):
        """
        Inits the internal serializer.

        Parameters
        ----------
        schema_location: str
            Specify the xsi:schemaLocation attribute value
        no_namespace_schema_location: str
            Specify the xsi:noNamespaceSchemaLocation attribute value
        """
        config = SerializerConfig(
            pretty_print=True,
            schema_location=schema_location,
            no_namespace_schema_location=no_namespace_schema_location,
        )
        self.serializer = XmlSerializer(config=config)
예제 #19
0
 def test_render_no_dataclass(self):
     with self.assertRaises(ModelInspectionError) as cm:
         XmlSerializer().render(self)
     self.assertEqual(f"Object {self.__class__} is not a dataclass.",
                      str(cm.exception))
예제 #20
0
def xml_serializer(xml_context, serializer_config):
    return XmlSerializer(context=xml_context, config=serializer_config)
예제 #21
0
 def render(self) -> str:
     name = self.__class__.__name__
     xml = XmlSerializer(pretty_print=True,
                         xml_declaration=False).render(self)
     start = xml.find(">") + 1
     return xml[start:].replace(f"</{name}>", "").strip()
예제 #22
0
class Application(SIPApplication):
    def __init__(self, *, config: Configuration) -> None:
        self.config = config

        self.serializer = XmlSerializer(config=SerializerConfig(
            pretty_print=False))
        self.parser = XmlParser(context=XmlContext())
        self.requests: WeakValueDictionary[str,
                                           Future] = WeakValueDictionary({})
        super().__init__()

    def start(self):
        notification_center = NotificationCenter()
        notification_center.add_observer(self, name='SIPEngineGotMessage')
        notification_center.add_observer(self, name='SIPMessageDidSucceed')
        notification_center.add_observer(self, name='SIPMessageDidFail')
        notification_center.add_observer(self, name='SIPApplicationDidStart')
        super().start(MemoryStorage())

    async def send_request(self, arc_name: str, scaip_request: ScaipRequest):
        logger.info(f"send_request to {arc_name}: {scaip_request}")

        config = self.config
        arc_config = config.get_arc_config(arc_name)

        if not arc_config:
            raise ValueError(f"no configuration found for ARC {arc_name}")

        xml_model = scaip_request.to_xml_model()
        xml_str = self.serializer.render(xml_model)

        result = self.new_result_future(scaip_request.reference)
        if scaip_request.caller_id.startswith(
                "sip") and scaip_request.caller_id != "sip:":
            caller_id = URI(scaip_request.caller_id)
            sender = SIPURI(user=caller_id.user,
                            host=caller_id.host,
                            port=caller_id.port)
        else:
            sender = self.get_user_agent_uri()

        receiver = SIPURI(user=arc_config.username,
                          host=arc_config.hostname,
                          port=arc_config.port)
        message = Message(FromHeader(sender), ToHeader(receiver),
                          RouteHeader(receiver), 'application/scaip+xml',
                          xml_str)
        message.send()
        logger.info(f"sent message: {xml_str}")

        scaip_response = await result

        logger.info(f"received response: {scaip_response}")

        return scaip_response

    def new_result_future(self, reference: str) -> Future:
        loop = asyncio.get_running_loop()
        result = loop.create_future()
        self.requests[reference] = result
        return result

    def get_user_agent_uri(self) -> SIPURI:
        sip_config = self.config.sip
        return SIPURI(user=sip_config.username,
                      host=sip_config.hostname,
                      port=sip_config.port)

    def _NH_SIPApplicationDidStart(self, notification):
        logger.info("SIPApplicationDidStart")

    def _NH_SIPMessageDidSucceed(self, notification):
        logger.info("SIPMessageDidSucceed")

    def _NH_SIPMessageDidFail(self, notification):
        logger.info("SIPMessageDidFail")

        message = notification.sender
        xml_model = self.parser.from_bytes(message.body, Mrq)

        result = self.requests.get(xml_model.ref, None)

        if result:
            # TODO: return proper error
            result.set_exception(
                HTTPException(status_code=500, detail="SIPMessageDidFail"))

    def _NH_SIPEngineGotMessage(self, notification):
        logger.info("SIPEngineGotMessage")
        logger.info(f"got XML: {notification.data.body}")
        xml_model = self.parser.from_bytes(notification.data.body, Mrs)
        scaip_response = ScaipResponse.from_xml_model(xml_model)

        result = self.requests.get(xml_model.ref, None)

        if result:
            result.set_result(scaip_response)
예제 #23
0
 def setUp(self):
     config = SerializerConfig(pretty_print=True)
     self.serializer = XmlSerializer(config=config, writer=LxmlEventWriter)
예제 #24
0
 def save(self):
     with self.path.open(mode="w") as file_obj:
         serialized = XmlSerializer(pretty_print=True).render(self.nml)
         serialized = serialized.split("\n")
         serialized = "\n".join(line.lstrip() for line in serialized)
         file_obj.write(serialized)
예제 #25
0
def write(size, obj, writer):
    with xsdata_temp_dir.joinpath(f"benchmark_{size}.xml").open("w") as f:
        serializer = XmlSerializer(writer=writer, context=context)
        serializer.write(f, obj)
예제 #26
0
파일: test_xml.py 프로젝트: nimish/xsdata
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))
예제 #27
0
fixtures = here.joinpath("fixtures")

is_travis = "TRAVIS" in os.environ


@dataclass
class Documentation:
    title: str
    skip_message: str
    source: str
    target: str


xml_parser = XmlParser()
json_parser = JsonParser()
xml_serializer = XmlSerializer(pretty_print=True)
json_serializer = JsonSerializer(indent=4)

xmls = sorted([
    xsd for xsd in fixtures.glob("defxmlschema/*/chapter*.xml")
    if not str(xsd).endswith("xsdata.xml")
])

total = 0
skipped = 0


@pytest.mark.parametrize("fixture", xmls, ids=lambda x: x.name)
def test_binding(fixture: Path):
    global total, skipped
    total += 1
예제 #28
0
 def setUp(self) -> None:
     self.serializer = XmlSerializer()
예제 #29
0
import sys
from pathlib import Path

from xsdata.formats.dataclass.parsers import XmlParser
from xsdata.formats.dataclass.serializers import XmlSerializer
from xsdata.formats.dataclass.serializers.config import SerializerConfig

from reqif.models import ReqIf

here = Path(__file__).parent

xml_fixture = here.joinpath("sample.xml")
parser = XmlParser()
config = SerializerConfig(pretty_print=True, encoding="ascii")
serializer = XmlSerializer(context=parser.context, config=config)

obj = parser.from_path(xml_fixture, ReqIf)
ns_map = {
    None: "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd",
    "xhtml": "http://www.w3.org/1999/xhtml",
}
serializer.write(sys.stdout, obj, ns_map=ns_map)
예제 #30
0
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])