Skip to content

Commit

Permalink
Introduce lxml TargetHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
tefra committed Aug 29, 2020
1 parent 208c48f commit 8ef2034
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 99 deletions.
116 changes: 116 additions & 0 deletions tests/formats/dataclass/parsers/test_handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
from unittest.case import TestCase

from tests import fixtures_dir
from tests.fixtures.books import BookForm
from tests.fixtures.books import Books
from xsdata.formats.dataclass.parsers.handlers import EventsHandler
from xsdata.formats.dataclass.parsers.handlers import LxmlIterHandler
from xsdata.formats.dataclass.parsers.handlers import LxmlSaxHandler
from xsdata.formats.dataclass.parsers.xml import XmlParser

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",
price=33.95,
pub_date="2001-01-10",
review="A masterpiece of the fine art of gossiping.",
),
]
)


class LxmlIterHandlerTests(TestCase):
def setUp(self) -> None:
self.parser = XmlParser(handler=LxmlIterHandler)

def test_process(self):
path = fixtures_dir.joinpath("books/books.xml")
self.assertEqual(books, self.parser.from_path(path, Books))
self.assertEqual({"brk": "urn:books"}, self.parser.namespaces.ns_map)

def test_process_with_xinclude(self):
path = fixtures_dir.joinpath("books/books-xinclude.xml")
ns_map = {"brk": "urn:books", "xi": "http://www.w3.org/2001/XInclude"}

self.parser.config.process_xinclude = True
self.assertEqual(books, self.parser.from_path(path, Books))
self.assertEqual(ns_map, self.parser.namespaces.ns_map)

def test_process_with_xinclude_from_memory(self):
path = fixtures_dir.joinpath("books/books-xinclude.xml")
ns_map = {"brk": "urn:books", "xi": "http://www.w3.org/2001/XInclude"}

self.parser.config.process_xinclude = True
self.parser.config.base_url = path.as_uri()
self.assertEqual(books, self.parser.from_bytes(path.read_bytes(), Books))
self.assertEqual(ns_map, self.parser.namespaces.ns_map)


class LxmlSaxHandlerTests(TestCase):
def setUp(self):
self.parser = XmlParser(handler=LxmlSaxHandler)

def test_process(self):
path = fixtures_dir.joinpath("books/books.xml")
self.assertEqual(books, self.parser.from_path(path, Books))
self.assertEqual({"brk": "urn:books"}, self.parser.namespaces.ns_map)

def test_close_with_no_objects_returns_none(self):
handler = LxmlSaxHandler(
clazz=Books, parser=self.parser, config=self.parser.config
)
self.assertIsNone(handler.close())


class EventsHandlerTests(TestCase):
def test_process(self):
events = [
("start-ns", "brk", "urn:books"),
("start", "{urn:books}books", {}, {"brk": "urn:books"}),
("start", "book", {"id": "bk001"}, {"brk": "urn:books"}),
("start", "author", {}, {"brk": "urn:books"}),
("end", "author", "Hightower, Kim", "\n "),
("start", "title", {}, {"brk": "urn:books"}),
("end", "title", "The First Book", "\n "),
("start", "genre", {}, {"brk": "urn:books"}),
("end", "genre", "Fiction", "\n "),
("start", "price", {}, {"brk": "urn:books"}),
("end", "price", "44.95", "\n "),
("start", "pub_date", {}, {"brk": "urn:books"}),
("end", "pub_date", "2000-10-01", "\n "),
("start", "review", {}, {"brk": "urn:books"}),
("end", "review", "An amazing story of nothing.", "\n "),
("end", "book", "\n ", "\n "),
("start", "book", {"id": "bk002"}, {"brk": "urn:books"}),
("start", "author", {}, {"brk": "urn:books"}),
("end", "author", "Nagata, Suanne", "\n "),
("start", "title", {}, {"brk": "urn:books"}),
("end", "title", "Becoming Somebody", "\n "),
("start", "genre", {}, {"brk": "urn:books"}),
("end", "genre", "Biography", "\n "),
("start", "price", {}, {"brk": "urn:books"}),
("end", "price", "33.95", "\n "),
("start", "pub_date", {}, {"brk": "urn:books"}),
("end", "pub_date", "2001-01-10", "\n "),
("start", "review", {}, {"brk": "urn:books"}),
("end", "review", "A masterpiece of the fine art of gossiping.", "\n "),
("end", "book", "\n ", "\n"),
("end", "{urn:books}books", "\n ", None),
]

parser = XmlParser(handler=EventsHandler)
self.assertEqual(books, parser.parse(events, Books))
self.assertEqual({}, parser.namespaces.ns_map)
2 changes: 1 addition & 1 deletion tests/formats/dataclass/parsers/test_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ class NodeParserTests(TestCase):
def test_parse(self):
@dataclass
class TestHandler(XmlHandler):
def process(self, source: Any, clazz: Type[T], config: ParserConfig) -> Any:
def process(self, source: Any) -> Any:
return Books()

parser = NodeParser(handler=TestHandler)
Expand Down
79 changes: 0 additions & 79 deletions tests/formats/dataclass/parsers/test_xml.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
from dataclasses import asdict
from dataclasses import dataclass
from dataclasses import field
from typing import List
from unittest import mock
from unittest.case import TestCase

from tests import fixtures_dir
from tests.fixtures.books import BookForm
from tests.fixtures.books import Books
from xsdata.formats.dataclass.models.elements import XmlText
from xsdata.formats.dataclass.parsers.config import ParserConfig
from xsdata.formats.dataclass.parsers.nodes import PrimitiveNode
from xsdata.formats.dataclass.parsers.nodes import SkipNode
from xsdata.formats.dataclass.parsers.xml import XmlParser
Expand Down Expand Up @@ -66,75 +59,3 @@ def test_emit_event(self):

mock_func.assert_called_once_with(a=1, b=2)
self.assertEqual({"{tns}barElement": "bar_element"}, self.parser.event_names)


class XmlParserIntegrationTest(TestCase):
def setUp(self):
super().setUp()
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",
price=33.95,
pub_date="2001-01-10",
review="A masterpiece of the fine art of gossiping.",
),
]
)

def test_parse(self):
path = fixtures_dir.joinpath("books/books.xml")
parser = XmlParser()
actual = parser.from_path(path, Books)
self.assertEqual(self.books, actual)
self.assertEqual({"brk": "urn:books"}, parser.namespaces.ns_map)

def test_parse_with_process_xinclude_true(self):
path = fixtures_dir.joinpath("books/books-xinclude.xml")
config = ParserConfig(process_xinclude=True)
parser = XmlParser(config=config)
actual = parser.from_path(path, Books)
self.assertEqual(self.books, actual)

def test_parse_from_memory_with_process_xinclude_true(self):
path = fixtures_dir.joinpath("books/books-xinclude.xml")
config = ParserConfig(process_xinclude=True, base_url=path.as_uri())
parser = XmlParser(config=config)
actual = parser.from_bytes(path.read_bytes(), Books)
self.assertEqual(self.books, actual)

def test_parse_with_fail_on_unknown_properties_false(self):
path = fixtures_dir.joinpath("books/books.xml")

@dataclass
class Book:
author: str = field(metadata=dict(type="Element"))

@dataclass
class MyBooks:
class Meta:
name = "books"

book: List[Book] = field(
default_factory=list, metadata=dict(type="Element")
)

config = ParserConfig(fail_on_unknown_properties=False)
parser = XmlParser(config=config)
actual = parser.from_path(path, MyBooks)
expected = {
"book": [{"author": "Hightower, Kim"}, {"author": "Nagata, Suanne"}]
}
self.assertEqual(expected, asdict(actual))
Loading

0 comments on commit 8ef2034

Please sign in to comment.