# -*- coding: utf-8 -*-
"""
Test cases related to DTD parsing and validation
"""
import unittest, sys
from .common_imports import (
etree, html, BytesIO, _bytes, _str,
HelperTestCase, make_doctest, skipIf,
fileInTestDir, fileUrlInTestDir, SimpleFSPath
)
class ETreeDtdTestCase(HelperTestCase):
def test_dtd(self):
pass
def test_dtd_file(self):
parse = etree.parse
tree = parse(fileInTestDir("test.xml"))
root = tree.getroot()
dtd = etree.DTD(fileInTestDir("test.dtd"))
self.assertTrue(dtd.validate(root))
def test_dtd_file_pathlike(self):
parse = etree.parse
tree = parse(fileInTestDir("test.xml"))
root = tree.getroot()
dtd = etree.DTD(SimpleFSPath(fileInTestDir("test.dtd")))
self.assertTrue(dtd.validate(root))
def test_dtd_stringio(self):
root = etree.XML(_bytes(""))
dtd = etree.DTD(BytesIO(""))
self.assertTrue(dtd.validate(root))
def test_dtd_parse_invalid(self):
fromstring = etree.fromstring
parser = etree.XMLParser(dtd_validation=True)
xml = _bytes('' %
fileInTestDir("test.dtd"))
self.assertRaises(etree.XMLSyntaxError,
fromstring, xml, parser=parser)
def test_dtd_parse_file_not_found(self):
fromstring = etree.fromstring
dtd_filename = fileUrlInTestDir("__nosuch.dtd")
parser = etree.XMLParser(dtd_validation=True)
xml = _bytes('' % dtd_filename)
self.assertRaises(etree.XMLSyntaxError,
fromstring, xml, parser=parser)
errors = None
try:
fromstring(xml, parser=parser)
except etree.XMLSyntaxError:
e = sys.exc_info()[1]
self.assertTrue(e.error_log)
self.assertTrue(parser.error_log)
errors = [entry.message for entry in e.error_log
if dtd_filename in entry.message]
self.assertTrue(errors)
def test_dtd_parse_valid(self):
parser = etree.XMLParser(dtd_validation=True)
xml = ('' %
fileUrlInTestDir("test.dtd"))
root = etree.fromstring(xml, parser=parser)
def test_dtd_parse_valid_file_url(self):
parser = etree.XMLParser(dtd_validation=True)
xml = ('' %
fileUrlInTestDir("test.dtd"))
root = etree.fromstring(xml, parser=parser)
def test_dtd_parse_valid_relative(self):
parser = etree.XMLParser(dtd_validation=True)
xml = ''
root = etree.fromstring(
xml, parser=parser, base_url=fileUrlInTestDir("test.xml"))
def test_dtd_parse_valid_relative_file_url(self):
parser = etree.XMLParser(dtd_validation=True)
xml = ''
root = etree.fromstring(
xml, parser=parser, base_url=fileUrlInTestDir("test.xml"))
def test_dtd_invalid(self):
root = etree.XML("")
dtd = etree.DTD(BytesIO(""))
self.assertRaises(etree.DocumentInvalid, dtd.assertValid, root)
def test_dtd_assertValid(self):
root = etree.XML("")
dtd = etree.DTD(BytesIO(""))
dtd.assertValid(root)
def test_dtd_internal(self):
root = etree.XML(_bytes('''
]>
'''))
dtd = etree.ElementTree(root).docinfo.internalDTD
self.assertTrue(dtd)
dtd.assertValid(root)
def test_dtd_internal_invalid(self):
root = etree.XML(_bytes('''
]>
'''))
dtd = etree.ElementTree(root).docinfo.internalDTD
self.assertTrue(dtd)
self.assertFalse(dtd.validate(root))
def test_dtd_invalid_duplicate_id(self):
root = etree.XML(_bytes('''
'''))
dtd = etree.DTD(BytesIO(_bytes("""
""")))
self.assertFalse(dtd.validate(root))
self.assertTrue(dtd.error_log)
self.assertTrue([error for error in dtd.error_log
if 'id1' in error.message])
def test_dtd_api_internal(self):
root = etree.XML(_bytes('''
]>
'''))
dtd = etree.ElementTree(root).docinfo.internalDTD
self.assertTrue(dtd)
dtd.assertValid(root)
seen = []
for el in dtd.iterelements():
if el.name == 'a':
self.assertEqual(2, len(el.attributes()))
for attr in el.iterattributes():
if attr.name == 'attr1':
self.assertEqual('enumeration', attr.type)
self.assertEqual('none', attr.default)
self.assertEqual('z', attr.default_value)
values = attr.values()
values.sort()
self.assertEqual(['x', 'y', 'z'], values)
else:
self.assertEqual('attr2', attr.name)
self.assertEqual('cdata', attr.type)
self.assertEqual('fixed', attr.default)
self.assertEqual('X', attr.default_value)
else:
self.assertEqual('b', el.name)
self.assertEqual(0, len(el.attributes()))
seen.append(el.name)
seen.sort()
self.assertEqual(['a', 'b'], seen)
self.assertEqual(2, len(dtd.elements()))
def test_internal_dtds(self):
for el_count in range(2, 5):
for attr_count in range(4):
root = etree.XML(_bytes('''
''' % (e, a) for a in range(attr_count) for e in range(el_count)
]) + ''.join(['''
''' % e for e in range(1, el_count)
]) + '''
''' + '' % '|'.join([
'el%d' % e for e in range(1, el_count)]) + '''
]>