Package lxml :: Package tests :: Module test_relaxng |
[hide private]
[frames] | no frames]

# Source Code for Module lxml.tests.test_relaxng

      1  # -*- coding: utf-8 -*-
      2
      3  """
      4  Test cases related to RelaxNG parsing and validation
      5  """
      6
      7  import unittest, sys, os.path
      8
      9  this_dir = os.path.dirname(__file__)
     10  if this_dir not in sys.path:
     11      sys.path.insert(0, this_dir) # needed for Py3
     12
     13  from common_imports import etree, BytesIO, _bytes, HelperTestCase, fileInTestDir
     14  from common_imports import doctest, make_doctest, skipif
     15
     16  try:
     17      import rnc2rng
     18  except ImportError:
     19      rnc2rng = None
     20
     21
     22 -class ETreeRelaxNGTestCase(HelperTestCase):
     23 -    def test_relaxng(self):
     24          tree_valid = self.parse('<a><b></b></a>')
     25          tree_invalid = self.parse('<a><c></c></a>')
     26          schema = self.parse('''\
     27  <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
     28    <zeroOrMore>
     29       <element name="b">
     30         <text />
     31       </element>
     32    </zeroOrMore>
     33  </element>
     34  ''')
     35          schema = etree.RelaxNG(schema)
     36          self.assertTrue(schema.validate(tree_valid))
     37          self.assertFalse(schema.error_log.filter_from_errors())
     38
     39          self.assertFalse(schema.validate(tree_invalid))
     40          self.assertTrue(schema.error_log.filter_from_errors())
     41
     42          self.assertTrue(schema.validate(tree_valid))             # repeat valid
     43          self.assertFalse(schema.error_log.filter_from_errors())  # repeat valid
     44
     45 -    def test_relaxng_stringio(self):
     46          tree_valid = self.parse('<a><b></b></a>')
     47          tree_invalid = self.parse('<a><c></c></a>')
     48          schema_file = BytesIO('''\
     49  <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
     50    <zeroOrMore>
     51       <element name="b">
     52         <text />
     53       </element>
     54    </zeroOrMore>
     55  </element>
     56  ''')
     57          schema = etree.RelaxNG(file=schema_file)
     58          self.assertTrue(schema.validate(tree_valid))
     59          self.assertFalse(schema.validate(tree_invalid))
     60
     61 -    def test_relaxng_elementtree_error(self):
     62          self.assertRaises(ValueError, etree.RelaxNG, etree.ElementTree())
     63
     64 -    def test_relaxng_error(self):
     65          tree_invalid = self.parse('<a><c></c></a>')
     66          schema = self.parse('''\
     67  <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
     68    <zeroOrMore>
     69       <element name="b">
     70         <text />
     71       </element>
     72    </zeroOrMore>
     73  </element>
     74  ''')
     75          schema = etree.RelaxNG(schema)
     76          self.assertFalse(schema.validate(tree_invalid))
     77          errors = schema.error_log
     78          self.assertTrue([log for log in errors
     79                           if log.level_name == "ERROR"])
     80          self.assertTrue([log for log in errors
     81                           if "not expect" in log.message])
     82
     83 -    def test_relaxng_invalid_schema(self):
     84          schema = self.parse('''\
     85  <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
     86    <zeroOrMore>
     87       <element name="b" />
     88    </zeroOrMore>
     89  </element>
     90  ''')
     91          self.assertRaises(etree.RelaxNGParseError,
     92                            etree.RelaxNG, schema)
     93
     94 -    def test_relaxng_invalid_schema2(self):
     95          schema = self.parse('''\
     96  <grammar xmlns="http://relaxng.org/ns/structure/1.0" />
     97  ''')
     98          self.assertRaises(etree.RelaxNGParseError,
     99                            etree.RelaxNG, schema)
    100
    101 -    def test_relaxng_invalid_schema3(self):
    102          schema = self.parse('''\
    103  <grammar xmlns="http://relaxng.org/ns/structure/1.0">
    104    <define name="test">
    105      <element name="test"/>
    106    </define>
    107  </grammar>
    108  ''')
    109          self.assertRaises(etree.RelaxNGParseError,
    110                            etree.RelaxNG, schema)
    111
    112 -    def test_relaxng_invalid_schema4(self):
    113          # segfault
    114          schema = self.parse('''\
    115  <element name="a" xmlns="mynamespace" />
    116  ''')
    117          self.assertRaises(etree.RelaxNGParseError,
    118                            etree.RelaxNG, schema)
    119
    120 -    def test_relaxng_include(self):
    121          # this will only work if we access the file through path or
    122          # file object..
    123          f = open(fileInTestDir('test1.rng'), 'rb')
    124          try:
    125              schema = etree.RelaxNG(file=f)
    126          finally:
    127              f.close()
    128
    129 -    def test_relaxng_shortcut(self):
    130          tree_valid = self.parse('<a><b></b></a>')
    131          tree_invalid = self.parse('<a><c></c></a>')
    132          schema = self.parse('''\
    133  <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
    134    <zeroOrMore>
    135       <element name="b">
    136         <text />
    137       </element>
    138    </zeroOrMore>
    139  </element>
    140  ''')
    141          self.assertTrue(tree_valid.relaxng(schema))
    142          self.assertFalse(tree_invalid.relaxng(schema))
    143
    144 -    def test_multiple_elementrees(self):
    145          tree = self.parse('<a><b>B</b><c>C</c></a>')
    146          schema = etree.RelaxNG( self.parse('''\
    147  <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
    148    <element name="b">
    149      <text />
    150    </element>
    151    <element name="c">
    152      <text />
    153    </element>
    154  </element>
    155  ''') )
    156          self.assertTrue(schema.validate(tree))
    157          self.assertFalse(schema.error_log.filter_from_errors())
    158
    159          self.assertTrue(schema.validate(tree))                   # repeat valid
    160          self.assertFalse(schema.error_log.filter_from_errors())  # repeat valid
    161
    162          schema = etree.RelaxNG( self.parse('''\
    163  <element name="b" xmlns="http://relaxng.org/ns/structure/1.0">
    164    <text />
    165  </element>
    166  ''') )
    167          c_tree = etree.ElementTree(tree.getroot()[1])
    168          self.assertEqual(self._rootstring(c_tree), _bytes('<c>C</c>'))
    169          self.assertFalse(schema.validate(c_tree))
    170          self.assertTrue(schema.error_log.filter_from_errors())
    171
    172          b_tree = etree.ElementTree(tree.getroot()[0])
    173          self.assertEqual(self._rootstring(b_tree), _bytes('<b>B</b>'))
    174          self.assertTrue(schema.validate(b_tree))
    175          self.assertFalse(schema.error_log.filter_from_errors())
    176
    177 -class RelaxNGCompactTestCase(HelperTestCase):
    178
    179      pytestmark = skipif('rnc2rng is None')
    180
    181 -    def test_relaxng_compact(self):
    182          tree_valid = self.parse('<a><b>B</b><c>C</c></a>')
    183          tree_invalid = self.parse('<a><b></b></a>')
    184          schema = etree.RelaxNG(file=fileInTestDir('test.rnc'))
    185          self.assertTrue(schema.validate(tree_valid))
    186          self.assertFalse(schema.validate(tree_invalid))
    187
    188 -    def test_relaxng_compact_file_obj(self):
    189          f = open(fileInTestDir('test.rnc'), 'rb')
    190          try:
    191              schema = etree.RelaxNG(file=f)
    192          finally:
    193              f.close()
    194
    195 -    def test_relaxng_compact_str(self):
    196          tree_valid = self.parse('<a><b>B</b></a>')
    197          rnc_str = 'element a { element b { "B" } }'
    198          schema = etree.RelaxNG.from_rnc_string(rnc_str)
    199          self.assertTrue(schema.validate(tree_valid))
    200
    201
    202 -def test_suite():
    203      suite = unittest.TestSuite()
    204      suite.addTests([unittest.makeSuite(ETreeRelaxNGTestCase)])
    205      suite.addTests(
    206          [make_doctest('../../../doc/validation.txt')])
    207      if rnc2rng is not None:
    208          suite.addTests([unittest.makeSuite(RelaxNGCompactTestCase)])
    209      return suite
    210
    211  if __name__ == '__main__':
    212      print('to test use test.py %s' % __file__)
    213