# -*- coding: utf-8 -*-
"""
Test cases related to XML Schema parsing and validation
"""
import unittest, sys, os.path
this_dir = os.path.dirname(__file__)
if this_dir not in sys.path:
sys.path.insert(0, this_dir) # needed for Py3
from common_imports import etree, BytesIO, HelperTestCase, fileInTestDir
from common_imports import doctest, make_doctest
class ETreeXMLSchemaTestCase(HelperTestCase):
def test_xmlschema(self):
tree_valid = self.parse('')
tree_invalid = self.parse('')
schema = self.parse('''
''')
schema = etree.XMLSchema(schema)
self.assert_(schema.validate(tree_valid))
self.assert_(not schema.validate(tree_invalid))
def test_xmlschema_default_attributes(self):
schema = self.parse('''
''')
schema = etree.XMLSchema(schema, attribute_defaults=True)
tree = self.parse('')
root = tree.getroot()
self.assertEquals('ho', root[0].get('hardy'))
self.assertEquals(None, root[1].get('hardy'))
self.assertEquals('ho', root[2].get('hardy'))
self.assertEquals(None, root[3].get('hardy'))
self.assert_(schema(tree))
root = tree.getroot()
self.assertEquals('ho', root[0].get('hardy'))
self.assertEquals('hey', root[1].get('hardy'))
self.assertEquals('ho', root[2].get('hardy'))
self.assertEquals('hey', root[3].get('hardy'))
def test_xmlschema_parse(self):
schema = self.parse('''
''')
schema = etree.XMLSchema(schema)
parser = etree.XMLParser(schema=schema)
tree_valid = self.parse('', parser=parser)
self.assertEquals('a', tree_valid.getroot().tag)
self.assertRaises(etree.XMLSyntaxError,
self.parse, '', parser=parser)
def test_xmlschema_parse_default_attributes(self):
# does not work as of libxml2 2.7.3
schema = self.parse('''
''')
schema = etree.XMLSchema(schema)
parser = etree.XMLParser(schema=schema, attribute_defaults=True)
tree_valid = self.parse('',
parser=parser)
root = tree_valid.getroot()
self.assertEquals('ho', root[0].get('hardy'))
self.assertEquals('hey', root[1].get('hardy'))
self.assertEquals('ho', root[2].get('hardy'))
self.assertEquals('hey', root[3].get('hardy'))
def test_xmlschema_parse_default_attributes_schema_config(self):
# does not work as of libxml2 2.7.3
schema = self.parse('''
''')
schema = etree.XMLSchema(schema, attribute_defaults=True)
parser = etree.XMLParser(schema=schema)
tree_valid = self.parse('',
parser=parser)
root = tree_valid.getroot()
self.assertEquals('ho', root[0].get('hardy'))
self.assertEquals('hey', root[1].get('hardy'))
self.assertEquals('ho', root[2].get('hardy'))
self.assertEquals('hey', root[3].get('hardy'))
def test_xmlschema_parse_fixed_attributes(self):
# does not work as of libxml2 2.7.3
schema = self.parse('''
''')
schema = etree.XMLSchema(schema)
parser = etree.XMLParser(schema=schema, attribute_defaults=True)
tree_valid = self.parse('',
parser=parser)
root = tree_valid.getroot()
self.assertEquals('hey', root[0].get('hardy'))
self.assertEquals('hey', root[1].get('hardy'))
self.assertEquals('hey', root[2].get('hardy'))
def test_xmlschema_stringio(self):
schema_file = BytesIO('''
''')
schema = etree.XMLSchema(file=schema_file)
parser = etree.XMLParser(schema=schema)
tree_valid = self.parse('', parser=parser)
self.assertEquals('a', tree_valid.getroot().tag)
self.assertRaises(etree.XMLSyntaxError,
self.parse, '', parser=parser)
def test_xmlschema_iterparse(self):
schema = self.parse('''
''')
schema = etree.XMLSchema(schema)
xml = BytesIO('')
events = [ (event, el.tag)
for (event, el) in etree.iterparse(xml, schema=schema) ]
self.assertEquals([('end', 'b'), ('end', 'a')],
events)
def test_xmlschema_iterparse_fail(self):
schema = self.parse('''
''')
schema = etree.XMLSchema(schema)
self.assertRaises(
etree.XMLSyntaxError,
list, etree.iterparse(BytesIO(''), schema=schema))
def test_xmlschema_elementtree_error(self):
self.assertRaises(ValueError, etree.XMLSchema, etree.ElementTree())
def test_xmlschema_invalid_schema1(self):
schema = self.parse('''\
''')
self.assertRaises(etree.XMLSchemaParseError,
etree.XMLSchema, schema)
def test_xmlschema_invalid_schema2(self):
schema = self.parse('')
self.assertRaises(etree.XMLSchemaParseError,
etree.XMLSchema, schema)
def test_xmlschema_file(self):
# this will only work if we access the file through path or
# file object..
f = open(fileInTestDir('test.xsd'), 'rb')
try:
schema = etree.XMLSchema(file=f)
finally:
f.close()
tree_valid = self.parse('')
self.assert_(schema.validate(tree_valid))
def test_xmlschema_import_file(self):
# this will only work if we access the file through path or
# file object..
schema = etree.XMLSchema(file=fileInTestDir('test_import.xsd'))
tree_valid = self.parse(
'')
self.assert_(schema.validate(tree_valid))
def test_xmlschema_shortcut(self):
tree_valid = self.parse('')
tree_invalid = self.parse('')
schema = self.parse('''\
''')
self.assert_(tree_valid.xmlschema(schema))
self.assert_(not tree_invalid.xmlschema(schema))
class ETreeXMLSchemaResolversTestCase(HelperTestCase):
resolver_schema_int = BytesIO("""\
""")
resolver_schema_int2 = BytesIO("""\
""")
resolver_schema_ext = """\
"""
class simple_resolver(etree.Resolver):
def __init__(self, schema):
self.schema = schema
def resolve(self, url, id, context):
assert url == 'XXX.xsd'
return self.resolve_string(self.schema, context)
# tests:
def test_xmlschema_resolvers(self):
# test that resolvers work with schema.
parser = etree.XMLParser()
parser.resolvers.add(self.simple_resolver(self.resolver_schema_ext))
schema_doc = etree.parse(self.resolver_schema_int, parser = parser)
schema = etree.XMLSchema(schema_doc)
def test_xmlschema_resolvers_root(self):
# test that the default resolver will get called if there's no
# specific parser resolver.
root_resolver = self.simple_resolver(self.resolver_schema_ext)
etree.get_default_parser().resolvers.add(root_resolver)
schema_doc = etree.parse(self.resolver_schema_int)
schema = etree.XMLSchema(schema_doc)
etree.get_default_parser().resolvers.remove(root_resolver)
def test_xmlschema_resolvers_noroot(self):
# test that the default resolver will not get called when a
# more specific resolver is registered.
class res_root(etree.Resolver):
def resolve(self, url, id, context):
assert False
return None
root_resolver = res_root()
etree.get_default_parser().resolvers.add(root_resolver)
parser = etree.XMLParser()
parser.resolvers.add(self.simple_resolver(self.resolver_schema_ext))
schema_doc = etree.parse(self.resolver_schema_int, parser = parser)
schema = etree.XMLSchema(schema_doc)
etree.get_default_parser().resolvers.remove(root_resolver)
def test_xmlschema_nested_resolvers(self):
# test that resolvers work in a nested fashion.
resolver_schema = self.resolver_schema_ext
class res_nested(etree.Resolver):
def __init__(self, ext_schema):
self.ext_schema = ext_schema
def resolve(self, url, id, context):
assert url == 'YYY.xsd'
return self.resolve_string(self.ext_schema, context)
class res(etree.Resolver):
def __init__(self, ext_schema_1, ext_schema_2):
self.ext_schema_1 = ext_schema_1
self.ext_schema_2 = ext_schema_2
def resolve(self, url, id, context):
assert url == 'XXX.xsd'
new_parser = etree.XMLParser()
new_parser.resolvers.add(res_nested(self.ext_schema_2))
new_schema_doc = etree.parse(self.ext_schema_1, parser = new_parser)
new_schema = etree.XMLSchema(new_schema_doc)
return self.resolve_string(resolver_schema, context)
parser = etree.XMLParser()
parser.resolvers.add(res(self.resolver_schema_int2, self.resolver_schema_ext))
schema_doc = etree.parse(self.resolver_schema_int, parser = parser)
schema = etree.XMLSchema(schema_doc)
def test_suite():
suite = unittest.TestSuite()
suite.addTests([unittest.makeSuite(ETreeXMLSchemaTestCase)])
suite.addTests([unittest.makeSuite(ETreeXMLSchemaResolversTestCase)])
suite.addTests(
[make_doctest('../../../doc/validation.txt')])
return suite
if __name__ == '__main__':
print('to test use test.py %s' % __file__)