Exemple #1
0
    def check_errors(self, path, expected):
        """
        Checks schema or validation errors, checking information completeness of the
        instances and those number against expected.

        :param path: the path of the test case.
        :param expected: the number of expected errors.
        """
        for e in self.errors:
            error_string = unicode_type(e)
            self.assertTrue(e.path, "Missing path for: %s" % error_string)
            self.assertTrue(e.namespaces,
                            "Missing namespaces for: %s" % error_string)
            self.check_namespace_prefixes(error_string)

        if not self.errors and expected:
            raise ValueError("{!r}: found no errors when {} expected.".format(
                path, expected))
        elif len(self.errors) != expected:
            num_errors = len(self.errors)
            if num_errors == 1:
                msg = "{!r}: n.{} errors expected, found {}:\n\n{}"
            elif num_errors <= 5:
                msg = "{!r}: n.{} errors expected, found {}. Errors follow:\n\n{}"
            else:
                msg = "{!r}: n.{} errors expected, found {}. First five errors follow:\n\n{}"

            error_string = '\n++++++++++\n\n'.join(
                [unicode_type(e) for e in self.errors[:5]])
            raise ValueError(
                msg.format(path, expected, len(self.errors), error_string))
Exemple #2
0
 def check_xsd_file_with_lxml(self, xmlschema_time):
     start_time = time.time()
     lxs = lxml_etree.parse(xsd_file)
     try:
         lxml_etree.XMLSchema(lxs.getroot())
     except lxml_etree.XMLSchemaParseError as err:
         if not self.errors:
             print(
                 "\nSchema error with lxml.etree.XMLSchema for file {!r} ({}): {}"
                 .format(xsd_file, self.__class__.__name__,
                         unicode_type(err)))
     else:
         if self.errors:
             print(
                 "\nUnrecognized errors with lxml.etree.XMLSchema for file {!r} ({}): {}"
                 .format(
                     xsd_file, self.__class__.__name__,
                     '\n++++++\n'.join(
                         [unicode_type(e) for e in self.errors])))
         lxml_schema_time = time.time() - start_time
         if lxml_schema_time >= xmlschema_time:
             print(
                 "\nSlower lxml.etree.XMLSchema ({:.3f}s VS {:.3f}s) with file {!r} ({})"
                 .format(lxml_schema_time, xmlschema_time, xsd_file,
                         self.__class__.__name__))
Exemple #3
0
    def check_errors(self, path, expected):
        """
        Checks schema or validation errors, checking information completeness of the
        instances and those number against expected.

        :param path: the path of the test case.
        :param expected: the number of expected errors.
        """
        for e in self.errors:
            error_string = unicode_type(e)
            self.assertTrue(e.path, "Missing path for: %s" % error_string)
            self.assertTrue(e.namespaces, "Missing namespaces for: %s" % error_string)
            self.check_namespace_prefixes(error_string)

        if not self.errors and expected:
            raise ValueError("found no errors when %d expected." % expected)
        elif len(self.errors) != expected:
            num_errors = len(self.errors)
            if num_errors == 1:
                msg = "{!r}: n.{} errors expected, found {}:\n\n{}"
            elif num_errors <= 5:
                msg = "{!r}: n.{} errors expected, found {}. Errors follow:\n\n{}"
            else:
                msg = "{!r}: n.{} errors expected, found {}. First five errors follow:\n\n{}"

            error_string = '\n++++++++++\n\n'.join([unicode_type(e) for e in self.errors[:5]])
            raise ValueError(msg.format(path, expected, len(self.errors), error_string))
Exemple #4
0
    def test_date_decoding(self):
        # Issue #136
        schema = xmlschema.XMLSchema("""<?xml version="1.0" encoding="utf-8"?>
            <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0">
                <xs:element name="Date">
                    <xs:simpleType>
                        <xs:restriction base="xs:date">
                            <xs:minInclusive value="2000-01-01"/>
                            <xs:maxInclusive value="2099-12-31"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
            </xs:schema>""")

        self.assertEqual(schema.to_dict("<Date>2019-01-01</Date>"),
                         '2019-01-01')
        self.assertEqual(
            schema.to_dict("<Date>2019-01-01</Date>", datetime_types=True),
            datatypes.Date10.fromstring('2019-01-01'))

        data, errors = schema.to_dict("<Date>2019-01-01</Date>",
                                      validation='lax')
        self.assertEqual(data, '2019-01-01')
        self.assertEqual(errors, [])

        data, errors = schema.to_dict("<Date>2019-01-01</Date>",
                                      validation='lax',
                                      datetime_types=True)
        self.assertEqual(data, datatypes.Date10.fromstring('2019-01-01'))
        self.assertEqual(errors, [])

        data, errors = schema.to_dict("<Date>1999-12-31</Date>",
                                      validation='lax')
        self.assertEqual(data, '1999-12-31')
        self.assertEqual(len(errors), 1)
        self.assertIn('value has to be greater or equal than',
                      unicode_type(errors[0]))

        data, errors = schema.to_dict("<Date>1999-12-31</Date>",
                                      validation='lax',
                                      datetime_types=True)
        self.assertEqual(data, datatypes.Date10.fromstring('1999-12-31'))
        self.assertEqual(len(errors), 1)

        data, errors = schema.to_dict("<Date>2019</Date>", validation='lax')
        self.assertIsNone(data)
        self.assertEqual(len(errors), 1)

        with self.assertRaises(XMLSchemaValidationError):
            schema.to_dict("<Date>2019</Date>")

        data, errors = schema.to_dict("<Date>2019</Date>", validation='lax')
        self.assertIsNone(data)
        self.assertEqual(len(errors), 1)
Exemple #5
0
 def check_lxml_schema(self, xmlschema_time):
     start_time = time.time()
     lxs = lxml_etree.parse(xsd_file)
     try:
         lxml_etree.XMLSchema(lxs.getroot())
     except lxml_etree.XMLSchemaParseError as err:
         if not self.errors:
             print("\nSchema error with lxml.etree.XMLSchema for file {!r} ({}): {}".format(
                 xsd_file, self.__class__.__name__, unicode_type(err)
             ))
     else:
         if self.errors:
             print("\nUnrecognized errors with lxml.etree.XMLSchema for file {!r} ({}): {}".format(
                 xsd_file, self.__class__.__name__,
                 '\n++++++\n'.join([unicode_type(e) for e in self.errors])
             ))
         lxml_schema_time = time.time() - start_time
         if lxml_schema_time >= xmlschema_time:
             print(
                 "\nSlower lxml.etree.XMLSchema ({:.3f}s VS {:.3f}s) with file {!r} ({})".format(
                     lxml_schema_time, xmlschema_time, xsd_file, self.__class__.__name__
                 ))
Exemple #6
0
    def test_error_message(self):
        schema = self.schema_class(
            self.casepath('issues/issue_115/Rotation.xsd'))
        rotation_data = '<tns:rotation xmlns:tns="http://www.example.org/Rotation/" ' \
                        'pitch="0.0" roll="0.0" yaw="-1.0" />'

        message_lines = []
        try:
            schema.decode(rotation_data)
        except Exception as err:
            message_lines = unicode_type(err).split('\n')

        self.assertTrue(message_lines, msg="Empty error message!")
        self.assertEqual(message_lines[-6], 'Instance:')
        self.assertEqual(message_lines[-4].strip(), rotation_data)
        self.assertEqual(message_lines[-2], 'Path: /tns:rotation')
Exemple #7
0
    def test_error_message(self):
        schema = self.schema_class(
            self.casepath('issues/issue_115/Rotation.xsd'))
        rotation_data = {
            "@roll": 0.0,
            "@pitch": 0.0,
            "@yaw": -1.0  # <----- invalid value, must be between 0 and 360
        }

        message_lines = []
        try:
            schema.encode(rotation_data)
        except Exception as err:
            message_lines = unicode_type(err).split('\n')

        self.assertTrue(message_lines, msg="Empty error message!")
        self.assertEqual(message_lines[-4], 'Instance:')
        if sys.version_info < (3, 8):
            text = '<tns:rotation xmlns:tns="http://www.example.org/Rotation/" pitch="0.0" roll="0.0" yaw="-1.0" />'
        else:
            text = '<tns:rotation xmlns:tns="http://www.example.org/Rotation/" roll="0.0" pitch="0.0" yaw="-1.0" />'
        self.assertEqual(message_lines[-2].strip(), text)
Exemple #8
0
        def check_etree_encode(self, root, converter=None, **kwargs):
            namespaces = kwargs.get('namespaces', {})
            data1 = self.schema.decode(root, converter=converter, **kwargs)
            if isinstance(data1, tuple):
                data1 = data1[0]  # When validation='lax'

            for _ in iter_nested_items(data1, dict_class=ordered_dict_class):
                pass

            elem1 = self.schema.encode(data1,
                                       path=root.tag,
                                       converter=converter,
                                       **kwargs)
            if isinstance(elem1, tuple):
                # When validation='lax'
                if converter is not ParkerConverter:
                    for e in elem1[1]:
                        self.check_namespace_prefixes(unicode_type(e))
                elem1 = elem1[0]

            # Checks the encoded element to not contains reserved namespace prefixes
            if namespaces and all('ns%d' % k not in namespaces
                                  for k in range(10)):
                self.check_namespace_prefixes(
                    etree_tostring(elem1, namespaces=namespaces))

            # Main check: compare original a re-encoded tree
            try:
                etree_elements_assert_equal(root, elem1, strict=False)
            except AssertionError as err:
                # If the check fails retry only if the converter is lossy (eg. ParkerConverter)
                # or if the XML case has defaults taken from the schema or some part of data
                # decoding is skipped by schema wildcards (set the specific argument in testfiles).
                if converter not in (ParkerConverter, AbderaConverter,
                                     JsonMLConverter) and not skip_strict:
                    if debug_mode:
                        pdb.set_trace()
                    raise AssertionError(
                        str(err) +
                        msg_tmpl % "encoded tree differs from original")
                elif converter is ParkerConverter and any(
                        XSI_TYPE in e.attrib for e in root.iter()):
                    return  # can't check encode equivalence if xsi:type is provided
                else:
                    # Lossy or augmenting cases are checked after another decoding/encoding pass
                    data2 = self.schema.decode(elem1,
                                               converter=converter,
                                               **kwargs)
                    if isinstance(data2, tuple):
                        data2 = data2[0]

                    if sys.version_info >= (3, 6):
                        # For Python < 3.6 cannot ensure attribute decoding order
                        try:
                            self.assertEqual(
                                data1, data2,
                                msg_tmpl % "re-decoded data changed")
                        except AssertionError:
                            if debug_mode:
                                pdb.set_trace()
                            raise

                    elem2 = self.schema.encode(data2,
                                               path=root.tag,
                                               converter=converter,
                                               **kwargs)
                    if isinstance(elem2, tuple):
                        elem2 = elem2[0]

                    try:
                        etree_elements_assert_equal(elem1, elem2, strict=False)
                    except AssertionError as err:
                        if debug_mode:
                            pdb.set_trace()
                        raise AssertionError(
                            str(err) + msg_tmpl %
                            "encoded tree differs after second pass")
Exemple #9
0
    def test_schema(self):
        if debug_mode:
            print("\n##\n## Testing schema %s in debug mode.\n##" % rel_path)
            import pdb
            pdb.set_trace()

        if inspect:
            SchemaObserver.clear()

        def check_schema():
            if expected_errors > 0:
                xs = schema_class(xsd_file, validation='lax', locations=locations, defuse=defuse)
            else:
                xs = schema_class(xsd_file, locations=locations, defuse=defuse)

            errors_ = xs.all_errors

            if inspect:
                components_ids = set([id(c) for c in xs.iter_components()])
                missing = [c for c in SchemaObserver.components if id(c) not in components_ids]
                if any([c for c in missing]):
                    raise ValueError("schema missing %d components: %r" % (len(missing), missing))

            # Pickling test (only for Python 3, skip inspected schema classes test)
            if not inspect and PY3:
                deserialized_schema = pickle.loads(pickle.dumps(xs))
                self.assertTrue(isinstance(deserialized_schema, XMLSchemaBase))
                self.assertEqual(xs.built, deserialized_schema.built)

            # XPath API tests
            if not inspect and not errors_:
                context = ElementPathContext(xs)
                elements = [x for x in xs.iter()]
                context_elements = [x for x in context.iter() if isinstance(x, XsdValidator)]
                self.assertEqual(context_elements, [x for x in context.iter_descendants()])
                self.assertEqual(context_elements, elements)

            return errors_

        if expected_warnings > 0:
            with warnings.catch_warnings(record=True) as ctx:
                warnings.simplefilter("always")
                errors = check_schema()
                self.assertEqual(len(ctx), expected_warnings, "Wrong number of include/import warnings")
        else:
            errors = check_schema()

        # Checks errors completeness
        for e in errors:
            error_string = unicode_type(e)
            self.assertTrue(e.path, "Missing path for: %s" % error_string)
            self.assertTrue(e.namespaces, "Missing namespaces for: %s" % error_string)
            self.check_namespace_prefixes(error_string)

        num_errors = len(errors)
        if num_errors != expected_errors:
            print("\n%s: %r errors, %r expected." % (self.id()[13:], num_errors, expected_errors))
            if num_errors == 0:
                raise ValueError("found no errors when %d expected." % expected_errors)
            else:
                raise ValueError("n.%d errors expected, found %d: %s" % (
                    expected_errors, num_errors, '\n++++++\n'.join([str(e) for e in errors])
                ))
        else:
            self.assertTrue(True, "Successfully created schema for {}".format(xsd_file))