lxml.tests.test_relaxng

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  from __future__ import absolute_import
      8
      9  import unittest
     10
     11  from .common_imports import (
     12      etree, BytesIO, _bytes, HelperTestCase, fileInTestDir, make_doctest, skipif
     13  )
     14
     15  try:
     16      import rnc2rng
     17  except ImportError:
     18      rnc2rng = None
     19
     20
     21 -class ETreeRelaxNGTestCase(HelperTestCase):
     22 -    def test_relaxng(self):
     23          tree_valid = self.parse('<a><b></b></a>')
     24          tree_invalid = self.parse('<a><c></c></a>')
     25          schema = self.parse('''\
     26  <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
     27    <zeroOrMore>
     28       <element name="b">
     29         <text />
     30       </element>
     31    </zeroOrMore>
     32  </element>
     33  ''')
     34          schema = etree.RelaxNG(schema)
     35          self.assertTrue(schema.validate(tree_valid))
     36          self.assertFalse(schema.error_log.filter_from_errors())
     37
     38          self.assertFalse(schema.validate(tree_invalid))
     39          self.assertTrue(schema.error_log.filter_from_errors())
     40
     41          self.assertTrue(schema.validate(tree_valid))             # repeat valid
     42          self.assertFalse(schema.error_log.filter_from_errors())  # repeat valid
     43
     44 -    def test_relaxng_stringio(self):
     45          tree_valid = self.parse('<a><b></b></a>')
     46          tree_invalid = self.parse('<a><c></c></a>')
     47          schema_file = BytesIO('''\
     48  <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
     49    <zeroOrMore>
     50       <element name="b">
     51         <text />
     52       </element>
     53    </zeroOrMore>
     54  </element>
     55  ''')
     56          schema = etree.RelaxNG(file=schema_file)
     57          self.assertTrue(schema.validate(tree_valid))
     58          self.assertFalse(schema.validate(tree_invalid))
     59
     60 -    def test_relaxng_elementtree_error(self):
     61          self.assertRaises(ValueError, etree.RelaxNG, etree.ElementTree())
     62
     63 -    def test_relaxng_error(self):
     64          tree_invalid = self.parse('<a><c></c></a>')
     65          schema = self.parse('''\
     66  <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
     67    <zeroOrMore>
     68       <element name="b">
     69         <text />
     70       </element>
     71    </zeroOrMore>
     72  </element>
     73  ''')
     74          schema = etree.RelaxNG(schema)
     75          self.assertFalse(schema.validate(tree_invalid))
     76          errors = schema.error_log
     77          self.assertTrue([log for log in errors
     78                           if log.level_name == "ERROR"])
     79          self.assertTrue([log for log in errors
     80                           if "not expect" in log.message])
     81
     82 -    def test_relaxng_generic_error(self):
     83          tree_invalid = self.parse('''\
     84          <test>
     85            <reference id="my-ref">This is my unique ref.</reference>
     86            <data ref="my-ref">Valid data</data>
     87            <data ref="myref">Invalid data</data>
     88          </test>
     89          ''')
     90          schema = self.parse('''\
     91          <grammar datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
     92                   xmlns="http://relaxng.org/ns/structure/1.0">
     93            <define name="by-ref">
     94              <data type="IDREF"/>
     95            </define>
     96            <start>
     97              <element name="test">
     98                <zeroOrMore>
     99                  <element name="reference">
    100                    <attribute name="id">
    101                      <data type="ID"/>
    102                    </attribute>
    103                    <text/>
    104                  </element>
    105                </zeroOrMore>
    106                <zeroOrMore>
    107                  <element name="data">
    108                    <attribute name="ref">
    109                      <data type="IDREF"/>
    110                    </attribute>
    111                    <text/>
    112                  </element>
    113                </zeroOrMore>
    114              </element>
    115            </start>
    116          </grammar>
    117          ''')
    118
    119          schema = etree.RelaxNG(schema)
    120          self.assertFalse(schema.validate(tree_invalid))
    121          errors = schema.error_log
    122          self.assertTrue(errors)
    123          self.assertTrue([log for log in errors if "IDREF" in log.message])
    124          self.assertTrue([log for log in errors if "myref" in log.message])
    125
    126 -    def test_relaxng_invalid_schema(self):
    127          schema = self.parse('''\
    128  <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
    129    <zeroOrMore>
    130       <element name="b" />
    131    </zeroOrMore>
    132  </element>
    133  ''')
    134          self.assertRaises(etree.RelaxNGParseError,
    135                            etree.RelaxNG, schema)
    136
    137 -    def test_relaxng_invalid_schema2(self):
    138          schema = self.parse('''\
    139  <grammar xmlns="http://relaxng.org/ns/structure/1.0" />
    140  ''')
    141          self.assertRaises(etree.RelaxNGParseError,
    142                            etree.RelaxNG, schema)
    143
    144 -    def test_relaxng_invalid_schema3(self):
    145          schema = self.parse('''\
    146  <grammar xmlns="http://relaxng.org/ns/structure/1.0">
    147    <define name="test">
    148      <element name="test"/>
    149    </define>
    150  </grammar>
    151  ''')
    152          self.assertRaises(etree.RelaxNGParseError,
    153                            etree.RelaxNG, schema)
    154
    155 -    def test_relaxng_invalid_schema4(self):
    156          # segfault
    157          schema = self.parse('''\
    158  <element name="a" xmlns="mynamespace" />
    159  ''')
    160          self.assertRaises(etree.RelaxNGParseError,
    161                            etree.RelaxNG, schema)
    162
    163 -    def test_relaxng_include(self):
    164          # this will only work if we access the file through path or
    165          # file object..
    166          f = open(fileInTestDir('test1.rng'), 'rb')
    167          try:
    168              schema = etree.RelaxNG(file=f)
    169          finally:
    170              f.close()
    171
    172 -    def test_relaxng_shortcut(self):
    173          tree_valid = self.parse('<a><b></b></a>')
    174          tree_invalid = self.parse('<a><c></c></a>')
    175          schema = self.parse('''\
    176  <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
    177    <zeroOrMore>
    178       <element name="b">
    179         <text />
    180       </element>
    181    </zeroOrMore>
    182  </element>
    183  ''')
    184          self.assertTrue(tree_valid.relaxng(schema))
    185          self.assertFalse(tree_invalid.relaxng(schema))
    186
    187 -    def test_multiple_elementrees(self):
    188          tree = self.parse('<a><b>B</b><c>C</c></a>')
    189          schema = etree.RelaxNG( self.parse('''\
    190  <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
    191    <element name="b">
    192      <text />
    193    </element>
    194    <element name="c">
    195      <text />
    196    </element>
    197  </element>
    198  ''') )
    199          self.assertTrue(schema.validate(tree))
    200          self.assertFalse(schema.error_log.filter_from_errors())
    201
    202          self.assertTrue(schema.validate(tree))                   # repeat valid
    203          self.assertFalse(schema.error_log.filter_from_errors())  # repeat valid
    204
    205          schema = etree.RelaxNG( self.parse('''\
    206  <element name="b" xmlns="http://relaxng.org/ns/structure/1.0">
    207    <text />
    208  </element>
    209  ''') )
    210          c_tree = etree.ElementTree(tree.getroot()[1])
    211          self.assertEqual(self._rootstring(c_tree), _bytes('<c>C</c>'))
    212          self.assertFalse(schema.validate(c_tree))
    213          self.assertTrue(schema.error_log.filter_from_errors())
    214
    215          b_tree = etree.ElementTree(tree.getroot()[0])
    216          self.assertEqual(self._rootstring(b_tree), _bytes('<b>B</b>'))
    217          self.assertTrue(schema.validate(b_tree))
    218          self.assertFalse(schema.error_log.filter_from_errors())
    219
    220
    221 -class RelaxNGCompactTestCase(HelperTestCase):
    222
    223      pytestmark = skipif('rnc2rng is None')
    224
    225 -    def test_relaxng_compact(self):
    226          tree_valid = self.parse('<a><b>B</b><c>C</c></a>')
    227          tree_invalid = self.parse('<a><b></b></a>')
    228          schema = etree.RelaxNG(file=fileInTestDir('test.rnc'))
    229          self.assertTrue(schema.validate(tree_valid))
    230          self.assertFalse(schema.validate(tree_invalid))
    231
    232 -    def test_relaxng_compact_file_obj(self):
    233          with open(fileInTestDir('test.rnc'), 'r') as f:
    234              schema = etree.RelaxNG(file=f)
    235
    236          tree_valid = self.parse('<a><b>B</b><c>C</c></a>')
    237          tree_invalid = self.parse('<a><b></b></a>')
    238          self.assertTrue(schema.validate(tree_valid))
    239          self.assertFalse(schema.validate(tree_invalid))
    240
    241 -    def test_relaxng_compact_str(self):
    242          tree_valid = self.parse('<a><b>B</b></a>')
    243          tree_invalid = self.parse('<a><b>X</b></a>')
    244          rnc_str = 'element a { element b { "B" } }'
    245          schema = etree.RelaxNG.from_rnc_string(rnc_str)
    246          self.assertTrue(schema.validate(tree_valid))
    247          self.assertFalse(schema.validate(tree_invalid))
    248
    249
    250 -def test_suite():
    251      suite = unittest.TestSuite()
    252      suite.addTests([unittest.makeSuite(ETreeRelaxNGTestCase)])
    253      suite.addTests(
    254          [make_doctest('../../../doc/validation.txt')])
    255      if rnc2rng is not None:
    256          suite.addTests([unittest.makeSuite(RelaxNGCompactTestCase)])
    257      return suite
    258
    259  if __name__ == '__main__':
    260      print('to test use test.py %s' % __file__)
    261