def test_chain(): with xsc.Pool() as p1: class foo1(xsc.Element): xmlname = "foo" xmlns = "nix" class baz(xsc.Element): xmlns = "nix" with xsc.Pool(p1) as p2: class foo2(xsc.Element): xmlname = "foo" xmlns = "nix" class bar(xsc.Element): xmlns = "nix" assert p1.elementclass("nix", "foo") is foo1 assert p1.elementclass("nix", "bar") is xsc.Element assert p1.elementclass("nix", "baz") is baz assert p2.elementclass("nix", "foo") is foo2 assert p2.elementclass("nix", "bar") is bar assert p2.elementclass("nix", "baz") is baz
def test_chain2(): with xsc.Pool() as p1: class foo1(xsc.Element): xmlns = "nix" with xsc.Pool() as p2: class foo2(xsc.Element): xmlns = "nix" p = xsc.Pool(p1, p2) assert p.elementclass("nix", "foo2") is foo2
def test_stack(): with xsc.Pool() as r1: class foo1(xsc.Element): xmlname = "foo" xmlns = "nix" with xsc.Pool() as r2: class foo2(xsc.Element): xmlname = "foo" xmlns = "nix" assert r1.elementclass("nix", "foo") is foo1 assert r2.elementclass("nix", "foo") is foo2
def test_parsevalueattrs(recwarn): xmlns = "http://www.example.com/required2" # Parser should complain about attributes with illegal values, when a set of values is specified with xsc.Pool(): class Test(xsc.Element): xmlns = "http://www.example.com/required2" class Attrs(xsc.Element.Attrs): class withvalues(xsc.TextAttr): values = ("foo", "bar") node = parse.tree(b'<Test withvalues="bar"/>', parse.Expat(), parse.NS(xmlns), parse.Node(), validate=True) assert str(node[0]["withvalues"]) == "bar" parse.tree(b'<Test withvalues="baz"/>', parse.Expat(), parse.NS(xmlns), parse.Node(), validate=True) w = recwarn.pop(xsc.IllegalAttrValueWarning)
def printone(u): source = parse.URL(u) if isinstance(u, url.URL) else parse.Stream(u) node = parse.tree(source, parse.Tidy(), parse.NS(html), parse.Node(base="", pool=xsc.Pool(html, xml))) if args.compact: node = node.normalized().compacted() node = node.pretty() print((node.string(encoding=sys.stdout.encoding)))
def test_parseemptyattribute(): e = parse.tree(b"<a target=''/>", parse.Expat(), parse.NS(html), parse.Node(pool=xsc.Pool(html)), validate=True) assert "target" in e[0].attrs
def test_noelementsortext(): with xsc.Pool(): class el1(xsc.Element): xmlns = "ns1" model = sims.NoElementsOrText() class el2(xsc.Element): xmlns = "ns2" e = el1() e.bytes(validate=True) e = el1("foo") with warnings.catch_warnings(record=True) as w: e.bytes(validate=True) assert len(w) == 1 assert issubclass(w[-1].category, sims.IllegalTextWarning) e = el1(php.php("gurk")) e.bytes(validate=True) e = el1(xsc.Comment("gurk")) e.bytes(validate=True) e = el1(el1()) with warnings.catch_warnings(record=True) as w: e.bytes(validate=True) assert len(w) == 1 assert issubclass(w[-1].category, sims.ElementWarning) # Elements from a different namespace are OK e = el1(el2()) e.bytes(validate=True)
def test_parserequiredattrs(recwarn): xmlns = "http://www.example.com/required" # Parser should complain about required attributes that are missing with xsc.Pool(): class Test(xsc.Element): xmlns = "http://www.example.com/required" class Attrs(xsc.Element.Attrs): class required(xsc.TextAttr): required = True node = parse.tree(b'<Test required="foo"/>', parse.Expat(), parse.NS(xmlns), parse.Node(), validate=True) assert str(node[0]["required"]) == "foo" parse.tree(b'<Test/>', parse.Expat(), parse.NS(xmlns), parse.Node(), validate=True) w = recwarn.pop(xsc.RequiredAttrMissingWarning) node = parse.tree(b'<Test required="foo"/>', parse.Expat(), parse.NS(xmlns), parse.Node(), validate=True) assert node[0].__class__ is xsc.Element assert node[0].xmlname == "Test" assert node[0].xmlns == xmlns
def test_base(): e = parse.tree(parse.String( b'<a xmlns="http://www.w3.org/1999/xhtml" href="gurk.html"/>', 'http://www.gurk.de/'), parse.Expat(ns=True), parse.Node(pool=xsc.Pool(html)), validate=True) assert str(e[0].attrs.href) == "http://www.gurk.de/gurk.html"
def xnd2ns(data): with xsc.Pool(): # don't pollute the defaultpool code = str(data) code = compile(code, "test.py", "exec") mod = types.ModuleType("test") mod.__file__ = "test.py" exec(code, mod.__dict__) return mod
def test_basics_entity(): def check(pool, xmlname, cls): assert pool.entityclass(xmlname) is cls assert pool.entity(xmlname).xmlname == xmlname pool = xsc.Pool(abbr) check(pool, "xist", abbr.xist) check(pool, "dontxist", xsc.Entity)
def check(input, output): node = parse.tree(f'<a title="{input}">{input}</a>'.encode("utf-8"), parse.SGMLOP(), parse.NS(a.xmlns), parse.Node(pool=xsc.Pool(a, bar, foo, chars)), validate=True) node = node.walknodes(a)[0] assert str(node) == output assert str(node.attrs.title) == output
def test_itermethods(): class pi(xsc.ProcInst): pass class en(xsc.Entity): pass class cr(xsc.CharRef): codepoint = 0x42 p1 = xsc.Pool(html.a, pi, en, cr) p2 = xsc.Pool(html.b, p1) assert html.a in list(p2.elements()) assert html.b in list(p2.elements()) assert pi in list(p2.procinsts()) assert en in list(p2.entities()) assert cr in list(p2.entities())
def test_basics_procinst(): def check(pool, xmlname, content, cls): assert pool.procinstclass(xmlname) is cls procinst = pool.procinst(xmlname, content) assert procinst.xmlname == xmlname assert procinst.content == content pool = xsc.Pool(php.php) check(pool, "php", "foo", php.php) check(pool, "nophp", "foo", xsc.ProcInst)
def test_parse_tidy_attrs(): e = parse.tree( b"<a xmlns:xl='http://www.w3.org/1999/xlink' xml:lang='de' xl:href='gurk.gif' href='gurk.gif'/>", parse.Tidy(), parse.NS(html), parse.Node(pool=xsc.Pool(html, xml, xlink)), validate=True) a = e.walknodes(html.a)[0] assert str(a.attrs["href"]) == "gurk.gif" assert str(a.attrs[xml.Attrs.lang]) == "de" assert str(a.attrs[xlink.Attrs.href]) == "gurk.gif"
def test_basics_element(): def check(pool, xmlns, xmlname, cls): assert pool.elementclass(xmlns, xmlname) is cls e = pool.element(xmlns, xmlname) assert (e.xmlns, e.xmlname) == (xsc.nsname(xmlns), xmlname) # empty pool pool = xsc.Pool() check(pool, html, "a", xsc.Element) # register one element pool = xsc.Pool(html.a) check(pool, html, "a", html.a) check(pool, html, "b", xsc.Element) # register a module pool = xsc.Pool(html) check(pool, html, "a", html.a) check(pool, html, "b", html.b) check(pool, html, "c", xsc.Element)
def check(encoding): node = xsc.Frag( html.div( php.php("echo $foo"), abbr.html(), html.div("gurk", class_="hurz"), "\u3042", )) s = node.bytes(encoding=encoding) node2 = parse.tree(s, parse.Expat(), parse.NS(html), xsc.Pool(html, php, abbr)) assert node == node2
def test_plain_entity(): with warnings.catch_warnings(record=True) as ws: node = parse.tree(b"<a xmlns='gurk'>&hurz;</a>", parse.Expat(ns=True), parse.Node(pool=xsc.Pool()), validate=True)[0][0] assert node.__class__ is xsc.Entity assert node.xmlname == "hurz" assert len(ws) == 2 assert all(issubclass(w.category, xsc.UndeclaredNodeWarning) for w in ws)
def xml2mod(strings, parser="etree", model="simple"): with xsc.Pool(): xnd = xml2xsc.makexnd(strings, parser=parser, model=model) code = str(xnd) print("Module source generated from XMLs:") print(code) code = compile(code, "test.py", "exec") mod = types.ModuleType("test") mod.__file__ = "test.py" exec(code, mod.__dict__) return mod
def test_plain_procinst(): with warnings.catch_warnings(record=True) as ws: node = parse.tree(b"<a xmlns='gurk'><?hurz text?></a>", parse.Expat(ns=True), parse.Node(pool=xsc.Pool()), validate=True)[0][0] assert node.__class__ is xsc.ProcInst assert node.xmlname == "hurz" assert node.content == "text" assert len(ws) == 2 assert all(issubclass(w.category, xsc.UndeclaredNodeWarning) for w in ws)
def test_plain_element(): with warnings.catch_warnings(record=True) as ws: node = parse.tree(b"<a xmlns='gurk'/>", parse.Expat(ns=True), parse.Node(pool=xsc.Pool()), validate=True)[0] assert node.__class__ is xsc.Element assert node.xmlns == "gurk" assert node.xmlname == "a" assert len(ws) == 1 assert issubclass(ws[0].category, xsc.UndeclaredNodeWarning)
def test_xmlns(): s = f"<z xmlns={doc.xmlns!r}><rb xmlns={ruby.xmlns!r}/><z/></z>".encode( "utf-8") e = parse.tree(s, parse.Expat(ns=True), parse.Node(pool=xsc.Pool(doc, ruby)), validate=True) assert e[0].xmlns == doc.xmlns assert e[0][0].xmlns == ruby.xmlns s = f"<a xmlns={html.xmlns!r}><a xmlns={ihtml.xmlns!r}/></a>".encode( "utf-8") e = parse.tree(s, parse.Expat(ns=True), parse.Node(pool=xsc.Pool(html, ihtml)), validate=True) assert isinstance(e[0], html.a) assert isinstance(e[0][0], ihtml.a) s = f"<a><a xmlns={ihtml.xmlns!r}/></a>".encode("utf-8") with warnings.catch_warnings(record=True) as ws: e = parse.tree(s, parse.Expat(), parse.NS(html), parse.Node(pool=xsc.Pool(ihtml)), validate=True) assert e[0].__class__ is xsc.Element assert e[0].xmlname == "a" assert e[0].xmlns == html.xmlns assert isinstance(e[0][0], ihtml.a) assert len(ws) == 1 assert issubclass(ws[0].category, xsc.UndeclaredNodeWarning) e = parse.tree(s, parse.Expat(), parse.NS(html), parse.Node(pool=xsc.Pool(html, ihtml)), validate=True) assert isinstance(e[0], html.a) assert isinstance(e[0][0], ihtml.a) s = f"<z xmlns={doc.xmlns!r}/>".encode("utf-8") e = parse.tree(s, parse.Expat(ns=True), parse.Node(pool=xsc.Pool(doc.z)), validate=True) assert isinstance(e[0], doc.z) with warnings.catch_warnings(record=True) as ws: e = parse.tree(s, parse.Expat(ns=True), parse.Node(pool=xsc.Pool()), validate=True) assert e[0].__class__ is xsc.Element assert e[0].xmlname == "z" assert e[0].xmlns == doc.xmlns assert len(ws) == 1 assert issubclass(ws[0].category, xsc.UndeclaredNodeWarning)
def test_elements(): with xsc.Pool(): class el11(xsc.Element): xmlname = "el1" xmlns = "ns1" class el12(xsc.Element): xmlname = "el2" xmlns = "ns1" class el21(xsc.Element): xmlname = "el1" xmlns = "ns2" class el22(xsc.Element): xmlname = "el2" xmlns = "ns2" el11.model = sims.Elements(el11, el21) e = el11() e.bytes(validate=True) e = el11("foo") with warnings.catch_warnings(record=True) as w: e.bytes(validate=True) assert len(w) == 1 assert issubclass(w[-1].category, sims.IllegalTextWarning) e = el11(php.php("gurk")) e.bytes(validate=True) e = el11(xsc.Comment("gurk")) e.bytes(validate=True) e = el11(el11()) e.bytes(validate=True) e = el11(el21()) e.bytes(validate=True) e = el11(el12()) with warnings.catch_warnings(record=True) as w: e.bytes(validate=True) assert len(w) == 1 assert issubclass(w[-1].category, sims.WrongElementWarning) e = el11(el22()) with warnings.catch_warnings(record=True) as w: e.bytes(validate=True) assert len(w) == 1 assert issubclass(w[-1].category, sims.WrongElementWarning)
def test_mixedattrnames(): with xsc.Pool() as r: class Attrs(xsc.Attrs): class a(xsc.TextAttr): xmlns = "test" xmlname = "A" class A(xsc.TextAttr): xmlns = "test" xmlname = "a" class Test(xsc.Element): xmlns = "test" class Attrs(xsc.Element.Attrs): class a(xsc.TextAttr): xmlname = "A" class A(xsc.TextAttr): xmlname = "a" xmlns = "test" node = Test({ Attrs.a: "a2", Attrs.A: "A2", }, a="a", A="A") def check(name, value): assert str(node[name]) == value assert str(node.attrs[name]) == value if isinstance(name, str): assert str(getattr(node.attrs, name)).swapcase() == value check("A", "a") check("a", "A") check(Test.Attrs.a, "a") check(Test.Attrs.A, "A") check(Attrs.a, "a2") check(Attrs.A, "A2")
def test_parsingmethods(): t = "abc\U00012345\u3042xyz" s = f'<?xml version="1.0" encoding="utf-8"?><a title="{t}">{t}</a>' b = s.encode("utf-8") def check(*pipeline): node = parse.tree(*pipeline, validate=True) node = node.walknodes(a)[0] assert str(node) == t assert str(node["title"]) == t prefixes = {None: a.xmlns} pool = xsc.Pool(a) check(b, parse.Expat(), parse.NS(a.xmlns), parse.Node(pool)) check(s, parse.Encoder(encoding="utf-8"), parse.Expat(), parse.NS(a.xmlns), parse.Node(pool)) check(parse.Iter(b), parse.Expat(), parse.NS(a.xmlns), parse.Node(pool)) # parse byte by byte check(parse.Stream(io.BytesIO(b), bufsize=1), parse.Expat(), parse.NS(a.xmlns), parse.Node(pool)) check(parse.ETree(cElementTree.fromstring(b), defaultxmlns=a.xmlns), parse.Node(pool))
def test_names2(): with xsc.Pool() as r: class el_(xsc.Element): xmlname = "el" class en_(xsc.Entity): xmlname = "en" class pi_(xsc.ProcInst): xmlname = "pi" class cr_(xsc.CharRef): xmlname = "cr" codepoint = 0x4242 # Test elements assert set(r.elements()) == {el_} # Test entities assert set(r.entities()) == {cr_, en_} # Test procinsts assert set(r.procinsts()) == {pi_}
def test_names(): # Test classes where the Python and the XML name differ with xsc.Pool() as pool: class element1(xsc.Element): xmlname = "-element" xmlns = "nix" class procinst1(xsc.ProcInst): xmlname = "-procinst" class entity1(xsc.Entity): xmlname = "-entity" class charref1(xsc.CharRef): xmlname = "-charref" codepoint = 42 class Attrs(xsc.Attrs): xmlns = "nix" class attr(xsc.TextAttr): xmlname = "-attr" xmlns = "nix" # elements assert pool.element1 is element1 assert pool.elementclass("nix", "-element") is element1 assert pool.element("nix", "-element") == element1() assert pool.elementclass("nix", "element1") is xsc.Element # make sure that the default pool didn't pick up the new class assert xsc.threadlocalpool.pool.elementclass("nix", "-element") is xsc.Element # procinsts assert pool.procinst1 is procinst1 assert pool.procinstclass("-procinst") is procinst1 assert pool.procinst("-procinst", "spam") == procinst1("spam") assert pool.procinstclass("procinst1") is xsc.ProcInst # make sure that the default pool didn't pick up the new class assert xsc.threadlocalpool.pool.procinstclass("-procinst") is xsc.ProcInst # entities assert pool.entity1 is entity1 assert pool.entityclass("-entity") is entity1 assert pool.entity("-entity") == entity1() assert pool.entityclass("entity1") is xsc.Entity # make sure that the default pool didn't pick up the new class assert xsc.threadlocalpool.pool.entityclass("-entity") is xsc.Entity # the charref is an entity too assert pool.entityclass("-charref") is charref1 assert pool.entity("-charref") == charref1() assert pool.entityclass("charref1") is xsc.Entity # make sure that the default pool didn't pick up the new class assert xsc.threadlocalpool.pool.entityclass("-charref") is xsc.Entity # attributes assert pool.attrkey("nix", "-attr") is Attrs.attr assert pool.attrkey("nix", "attr") == ("nix", "attr") # make sure that the default pool didn't pick up the new class assert xsc.threadlocalpool.pool.attrkey("nix", "-attr") == ("nix", "-attr")
def test_xmlns(): p = xsc.Pool(html) assert p.xmlns == html.xmlns
def test_textcomment(): pool = xsc.Pool() assert pool.text("foo") == xsc.Text("foo") assert pool.comment("foo") == xsc.Comment("foo")
## Copyright 1999-2017 by LivingLogic AG, Bayreuth/Germany ## Copyright 1999-2017 by Walter Dörwald ## ## All Rights Reserved ## ## See ll/xist/__init__.py for the license import warnings from ll.xist import xsc, sims from ll.xist.ns import html, php with xsc.Pool(): class el1(xsc.Element): model = sims.Empty() # The following tests are split into separate test functions, because ``pytest`` has problems otherwise def test_empty1(): e = el1() e.bytes(validate=True) def test_empty2(): e = el1("gurk") with warnings.catch_warnings(record=True) as w: e.bytes(validate=True) assert len(w) == 1