def test_group_fields(self): target = ClassFactory.create(attrs=AttrFactory.list(2)) target.attrs[0].restrictions.min_occurs = 10 target.attrs[0].restrictions.max_occurs = 15 target.attrs[1].restrictions.min_occurs = 5 target.attrs[1].restrictions.max_occurs = 20 expected = AttrFactory.create( name="attr_B_Or_attr_C", tag="Choice", index=0, types=[AttrTypeFactory.xs_any()], choices=[ AttrFactory.create( tag=target.attrs[0].tag, name="attr_B", types=target.attrs[0].types, ), AttrFactory.create( tag=target.attrs[1].tag, name="attr_C", types=target.attrs[1].types, ), ], ) expected_res = Restrictions(min_occurs=5, max_occurs=20) self.sanitizer.group_fields(target, list(target.attrs)) self.assertEqual(1, len(target.attrs)) self.assertEqual(expected, target.attrs[0]) self.assertEqual(expected_res, target.attrs[0].restrictions)
def test_dependencies(self): obj = ClassFactory.create( attrs=[ AttrFactory.create(types=[AttrTypeFactory.xs_decimal()]), AttrFactory.create(types=[ AttrTypeFactory.create(qname=QName(Namespace.XS.uri, "annotated"), forward=True) ]), AttrFactory.create(types=[ AttrTypeFactory.create( qname=QName(Namespace.XS.uri, "openAttrs")), AttrTypeFactory.create( qname=QName(Namespace.XS.uri, "localAttribute")), ]), ], extensions=[ ExtensionFactory.create(type=AttrTypeFactory.create( qname=QName(Namespace.XS.uri, "foobar"))), ExtensionFactory.create(type=AttrTypeFactory.create( qname=QName(Namespace.XS.uri, "foobar"))), ], inner=[ ClassFactory.create(attrs=AttrFactory.list( 2, types=AttrTypeFactory.list(1, qname="foo"))) ], ) expected = [ QName("{http://www.w3.org/2001/XMLSchema}openAttrs"), QName("{http://www.w3.org/2001/XMLSchema}localAttribute"), QName("{http://www.w3.org/2001/XMLSchema}foobar"), QName("{xsdata}foo"), ] self.assertEqual(expected, list(obj.dependencies()))
def test_dependencies(self): obj = ClassFactory.create( attrs=[ AttrFactory.create(types=[AttrTypeFactory.xs_decimal()]), AttrFactory.create( types=[ AttrTypeFactory.create(name="xs:annotated", forward_ref=True) ] ), AttrFactory.create( types=[ AttrTypeFactory.create(name="xs:openAttrs"), AttrTypeFactory.create(name="xs:localAttribute"), ] ), ], extensions=ExtensionFactory.list( 1, type=AttrTypeFactory.create(name="xs:localElement") ), inner=[ ClassFactory.create( attrs=AttrFactory.list(2, types=AttrTypeFactory.list(1, name="foo")) ) ], ) expected = { QName("{http://www.w3.org/2001/XMLSchema}localAttribute"), QName("{http://www.w3.org/2001/XMLSchema}localElement"), QName("{http://www.w3.org/2001/XMLSchema}openAttrs"), QName("{xsdata}foo"), } self.assertEqual(expected, obj.dependencies())
def test_sanitize_attribute_sequence(self): def len_sequential(target: Class): return len([ attr for attr in target.attrs if attr.restrictions.sequential ]) restrictions = Restrictions(max_occurs=2, sequential=True) target = ClassFactory.create(attrs=[ AttrFactory.create(restrictions=restrictions.clone()), AttrFactory.create(restrictions=restrictions.clone()), ]) attrs_clone = [attr.clone() for attr in target.attrs] self.sanitizer.process_attribute_sequence(target, target.attrs[0]) self.assertEqual(2, len_sequential(target)) target.attrs[0].restrictions.sequential = False self.sanitizer.process_attribute_sequence(target, target.attrs[0]) self.assertEqual(1, len_sequential(target)) self.sanitizer.process_attribute_sequence(target, target.attrs[1]) self.assertEqual(0, len_sequential(target)) target.attrs = attrs_clone target.attrs[1].restrictions.sequential = False self.sanitizer.process_attribute_sequence(target, target.attrs[0]) self.assertEqual(0, len_sequential(target)) target.attrs[0].restrictions.sequential = True target.attrs[0].restrictions.max_occurs = 0 target.attrs[1].restrictions.sequential = True self.sanitizer.process_attribute_sequence(target, target.attrs[0]) self.assertEqual(1, len_sequential(target))
def test_sanitize_attribute_sequence(self): def len_sequential(target): return len( [attr for attr in attrs if attr.restrictions.sequential]) restrictions = Restrictions(max_occurs=2, sequential=True) attrs = [ AttrFactory.create(restrictions=restrictions.clone()), AttrFactory.create(restrictions=restrictions.clone()), ] attrs_clone = [attr.clone() for attr in attrs] ClassUtils.sanitize_attribute_sequence(attrs, 0) self.assertEqual(2, len_sequential(attrs)) attrs[0].restrictions.sequential = False ClassUtils.sanitize_attribute_sequence(attrs, 0) self.assertEqual(1, len_sequential(attrs)) ClassUtils.sanitize_attribute_sequence(attrs, 1) self.assertEqual(0, len_sequential(attrs)) attrs_clone[1].restrictions.sequential = False ClassUtils.sanitize_attribute_sequence(attrs_clone, 0) self.assertEqual(0, len_sequential(attrs_clone))
def test_process_attribute(self, mock_find): target = ClassFactory.create(attrs=[ AttrFactory.create(types=[AttrTypeFactory.create("foo")]), AttrFactory.create(types=[AttrTypeFactory.create("bar")]), ]) mock_find.side_effect = [-1, 2] first_attr = target.attrs[0] second_attr = target.attrs[1] first_attr.restrictions.max_occurs = 2 attr_qname = first_attr.types[0].qname reference_attrs = AttrFactory.list(2) self.processor.create_substitutions() self.processor.substitutions[attr_qname] = reference_attrs self.processor.process_attribute(target, first_attr) self.assertEqual(4, len(target.attrs)) self.assertEqual(reference_attrs[0], target.attrs[0]) self.assertIsNot(reference_attrs[0], target.attrs[0]) self.assertEqual(reference_attrs[1], target.attrs[3]) self.assertIsNot(reference_attrs[1], target.attrs[3]) self.assertEqual(2, target.attrs[0].restrictions.max_occurs) self.assertEqual(2, target.attrs[3].restrictions.max_occurs) self.processor.process_attribute(target, second_attr) self.assertEqual(4, len(target.attrs))
def test_rename_dependency(self): attr_type = AttrTypeFactory.create("{foo}bar") target = ClassFactory.create( extensions=[ ExtensionFactory.create(), ExtensionFactory.create(type=attr_type.clone()), ], attrs=[ AttrFactory.create(), AttrFactory.create(types=[AttrTypeFactory.create(), attr_type.clone()]), ], inner=[ ClassFactory.create( extensions=[ExtensionFactory.create(type=attr_type.clone())], attrs=[ AttrFactory.create(), AttrFactory.create( types=[AttrTypeFactory.create(), attr_type.clone()] ), ], ) ], ) self.sanitizer.rename_dependency(target, "{foo}bar", "thug") dependencies = set(target.dependencies()) self.assertNotIn("{foo}bar", dependencies) self.assertIn("thug", dependencies)
def test_has_duplicate_attribute_names(self): obj = ClassFactory.create() obj.attrs.append(AttrFactory.create(name="a")) self.assertFalse(generator.has_duplicate_attrs(obj)) obj.attrs.append(AttrFactory.create(name="a")) self.assertTrue(generator.has_duplicate_attrs(obj))
def test_hash_attributes_names(self): obj = ClassFactory.create(attrs=[ AttrFactory.create(name="a", local_name="-"), AttrFactory.create(name="a", local_name="_"), ]) generator.hash_attributes_names(obj) self.assertEqual("lq", obj.attrs[0].name) self.assertEqual("xw", obj.attrs[1].name)
def test_process_attributes_prevent_duplicates(self): a = AttrFactory.create(name="a") a_a = AttrFactory.create(name="a") b = AttrFactory.create(name="b") obj = ClassFactory.create(attrs=[a, a_a, b]) generator.process_attributes(obj, []) self.assertEqual([a, b], obj.attrs)
def test_dependencies(self): obj = ClassFactory.create( attrs=[ AttrFactory.create(types=[AttrTypeFactory.xs_decimal()]), AttrFactory.create( types=[ AttrTypeFactory.create( qname=build_qname(Namespace.XS.uri, "annotated"), forward=True, ) ], choices=[ AttrFactory.create( name="x", types=[ AttrTypeFactory.create(qname="choiceAttr"), AttrTypeFactory.xs_string(), ], ), AttrFactory.create( name="x", types=[ AttrTypeFactory.create(qname="choiceAttrTwo"), AttrTypeFactory.create(qname="choiceAttrEnum"), ], ), ], ), AttrFactory.create(types=[ AttrTypeFactory.create( qname=build_qname(Namespace.XS.uri, "openAttrs")), AttrTypeFactory.create( qname=build_qname(Namespace.XS.uri, "localAttribute")), ]), ], extensions=[ ExtensionFactory.create(type=AttrTypeFactory.create( qname=build_qname(Namespace.XS.uri, "foobar"))), ExtensionFactory.create(type=AttrTypeFactory.create( qname=build_qname(Namespace.XS.uri, "foobar"))), ], inner=[ ClassFactory.create(attrs=AttrFactory.list( 2, types=AttrTypeFactory.list(1, qname="{xsdata}foo"))) ], ) expected = [ "choiceAttr", "choiceAttrTwo", "choiceAttrEnum", "{http://www.w3.org/2001/XMLSchema}openAttrs", "{http://www.w3.org/2001/XMLSchema}localAttribute", "{http://www.w3.org/2001/XMLSchema}foobar", "{xsdata}foo", ] self.assertCountEqual(expected, list(obj.dependencies()))
def test_constant_value(self): attr = AttrFactory.create(types=[AttrTypeFactory.xs_string()], default="foo") self.assertEqual('"foo"', self.filters.constant_value(attr)) attr = AttrFactory.create(types=[AttrTypeFactory.create(qname="foo")]) self.assertEqual("Foo", self.filters.constant_value(attr)) attr = AttrFactory.create(types=[AttrTypeFactory.create(alias="alias")]) self.assertEqual("Alias", self.filters.constant_value(attr))
def test_property_has_wild_attr(self): obj = ClassFactory.create() self.assertFalse(obj.has_wild_attr) obj.attrs.append(AttrFactory.create()) obj.attrs.append(AttrFactory.create()) self.assertFalse(obj.has_wild_attr) obj.attrs.append(AttrFactory.any()) self.assertTrue(obj.has_wild_attr)
def test_property_has_suffix_attr(self): obj = ClassFactory.create() self.assertFalse(obj.has_suffix_attr) obj.attrs.append(AttrFactory.create()) obj.attrs.append(AttrFactory.create()) self.assertFalse(obj.has_suffix_attr) obj.attrs[1].index = sys.maxsize self.assertTrue(obj.has_suffix_attr)
def test_merge_redefined_type_with_circular_group(self, mock_copy_group_attributes): source = ClassFactory.create() target = source.clone() target.container = Tag.REDEFINE first_attr = AttrFactory.create() second_attr = AttrFactory.create(name=source.name) target.attrs.extend((first_attr, second_attr)) self.validator.merge_redefined_type(source, target) mock_copy_group_attributes.assert_called_once_with(source, target, second_attr)
def test_process_attributes_prevent_duplicates_after_process(self, *args): obj = ClassFactory.create(attrs=[ AttrFactory.create(name="a."), AttrFactory.create(name="a-"), AttrFactory.create(name="a*"), ]) generator.process_attributes(obj, []) actual = [(attr.name, attr.local_name) for attr in obj.attrs] expected = [("ys4", "a."), ("ys0", "a-"), ("yso", "a*")] self.assertEqual(expected, actual)
def test_process_enumerations_with_mixed_types(self): obj = ClassFactory.create(attrs=[ AttrFactory.create(default="aaBB"), AttrFactory.create(default=1, types=[AttrTypeFactory.xs_int()]), ]) generator.process_enumerations(obj) actual = [(attr.name, attr.default) for attr in obj.attrs] expected = [("VALUE_1", 1), ("AA_BB", '"aaBB"')] self.assertEqual(expected, actual)
def test_process_attribute_default_enum(self, mock_find_enum, mock_promote_inner_class, mock_logger_warning): enum_one = ClassFactory.enumeration(1, qname="root") enum_one.attrs[0].default = "1" enum_one.attrs[0].name = "one" enum_two = ClassFactory.enumeration(1, qname="inner") enum_two.attrs[0].default = "2" enum_two.attrs[0].name = "two" enum_three = ClassFactory.enumeration(1, qname="missing_member") mock_find_enum.side_effect = [ None, enum_one, None, enum_two, enum_three, ] target = ClassFactory.create( qname="target", attrs=[ AttrFactory.create( types=[ AttrTypeFactory.create(), AttrTypeFactory.create(qname="foo"), ], default="1", ), AttrFactory.create( types=[ AttrTypeFactory.create(), AttrTypeFactory.create(qname="bar", forward=True), ], default="2", ), AttrFactory.create(default="3"), ], ) actual = [] for attr in target.attrs: self.sanitizer.process_attribute_default(target, attr) actual.append(attr.default) self.assertEqual(["@enum@root::one", "@enum@inner::two", None], actual) mock_promote_inner_class.assert_called_once_with(target, enum_two) mock_logger_warning.assert_called_once_with( "No enumeration member matched %s.%s default value `%s`", target.name, target.attrs[2].local_name, "3", )
def test_process_enumerations(self): obj = ClassFactory.create(attrs=[ AttrFactory.create(default="2020-12-13"), AttrFactory.create(default="2020-12-14"), ]) generator.process_enumerations(obj) actual = [(attr.name, attr.default) for attr in obj.attrs] expected = [ ("VALUE_2020_12_13", '"2020-12-13"'), ("VALUE_2020_12_14", '"2020-12-14"'), ] self.assertEqual(expected, actual)
def test_property_xml_type(self): attr = AttrFactory.create(tag=Tag.ELEMENT) self.assertEqual("Element", attr.xml_type) attr = AttrFactory.create(tag=Tag.ATTRIBUTE) self.assertEqual("Attribute", attr.xml_type) attr = AttrFactory.create(tag=Tag.ANY_ATTRIBUTE) self.assertEqual("Attributes", attr.xml_type) attr = AttrFactory.create(tag=Tag.ANY) self.assertEqual("Wildcard", attr.xml_type) attr = AttrFactory.create(tag=Tag.RESTRICTION) self.assertIsNone(attr.xml_type)
def test_process_attribute_default_with_optional_field(self): target = ClassFactory.create() attr = AttrFactory.create(fixed=True, default=2) attr.restrictions.min_occurs = 0 self.sanitizer.process_attribute_default(target, attr) self.assertFalse(attr.fixed) self.assertIsNone(attr.default)
def test_attribute_metadata_restrictions(self): attr = AttrFactory.create(tag=Tag.RESTRICTION) attr.restrictions.max_occurs = 2 attr.restrictions.required = False expected = {"max_occurs": 2} self.assertEqual(expected, attribute_metadata(attr, None))
def test_process_attribute_restrictions(self): restrictions = [ Restrictions(min_occurs=0, max_occurs=0, required=True), Restrictions(min_occurs=0, max_occurs=1, required=True), Restrictions(min_occurs=1, max_occurs=1, required=False), Restrictions(max_occurs=2, required=True), Restrictions(min_occurs=2, max_occurs=2, required=True), ] expected = [ {}, {}, { "required": True }, { "max_occurs": 2, "min_occurs": 0 }, { "max_occurs": 2, "min_occurs": 2 }, ] for idx, res in enumerate(restrictions): attr = AttrFactory.create(restrictions=res) self.sanitizer.process_attribute_restrictions(attr) self.assertEqual(expected[idx], res.asdict())
def test_create_default_attribute_with_any_type(self): extension = ExtensionFactory.create( type=AttrTypeFactory.xs_any(), restrictions=Restrictions(min_occurs=1, max_occurs=1, required=True), ) item = ClassFactory.create(extensions=[extension]) ClassExtensionHandler.create_default_attribute(item, extension) expected = AttrFactory.create( name="any_element", index=0, default=None, types=[extension.type.clone()], tag=Tag.ANY, namespace="##any", restrictions=Restrictions(min_occurs=1, max_occurs=1, required=True), ) self.assertEqual(1, len(item.attrs)) self.assertEqual(0, len(item.extensions)) self.assertEqual(expected, item.attrs[0])
def test_flatten_attribute_types_when_source_has_only_one_attribute( self, mock_find_class, mock_copy_inner_classes ): type_a = AttrTypeFactory.create(name="a") type_b = AttrTypeFactory.create(name="b") common = ClassFactory.create( name="bar", attrs=AttrFactory.list( 1, name="b", types=[type_b], restrictions=RestrictionsFactory.create(required=True, min_occurs=2), ), ) mock_find_class.return_value = common parent = ClassFactory.create() attr = AttrFactory.create( name="a", types=[type_a], restrictions=RestrictionsFactory.create(min_occurs=1), ) self.analyzer.flatten_attribute_types(parent, attr) self.assertEqual([type_b], attr.types) self.assertEqual( {"required": True, "min_occurs": 2}, attr.restrictions.asdict() ) mock_find_class.assert_called_once_with(parent.source_qname(type_a.name)) mock_copy_inner_classes.assert_called_once_with(common, parent)
def test_field_default_value_with_type_qname(self): attr = AttrFactory.create(types=[type_qname], default="xs:anyType") ns_map = {"xs": Namespace.XS.uri} self.assertEqual( 'QName("{http://www.w3.org/2001/XMLSchema}anyType")', self.filters.field_default_value(attr, ns_map), )
def test_copy_inner_classes(self): source = ClassFactory.create( inner=ClassFactory.list(2, package="a", module="b")) target = ClassFactory.create() ClassUtils.copy_inner_classes(source, target) # All good copy all self.assertEqual(2, len(target.inner)) ClassUtils.copy_inner_classes(source, target) # Inner classes exist skip self.assertEqual(2, len(target.inner)) source.inner.append(target) attr = AttrFactory.create(types=[ AttrTypeFactory.create(name=target.name, forward=True), AttrTypeFactory.create(name=target.name, forward=False), AttrTypeFactory.create(name="foobar"), ]) target.attrs.append(attr) ClassUtils.copy_inner_classes(source, target) # Inner class matches target self.assertEqual(2, len(target.inner)) for inner in target.inner: self.assertEqual(target.package, inner.package) self.assertEqual(target.module, inner.module) self.assertTrue(attr.types[0].circular) self.assertFalse(attr.types[1].circular) self.assertFalse(attr.types[2].circular)
def test_attribute_default_with_type_qname(self): attr = AttrFactory.create(types=[type_qname], default="xs:anyType") ns_map = {"xs": Namespace.XS.uri} self.assertEqual( 'QName("http://www.w3.org/2001/XMLSchema", "anyType")', attribute_default(attr, ns_map), )
def test_process_complex_extension_when_source_has_suffix_attr( self, mock_compare_attributes, mock_copy_attributes): mock_compare_attributes.return_value = ClassExtensionHandler.INCLUDES_NONE extension = ExtensionFactory.create() target = ClassFactory.create() source = ClassFactory.create() source.attrs.append(AttrFactory.create(index=sys.maxsize)) self.processor.process_complex_extension(source, target, extension) self.assertEqual(0, len(target.attrs)) target.attrs.append(AttrFactory.create()) self.processor.process_complex_extension(source, target, extension) self.assertEqual(2, mock_compare_attributes.call_count) mock_copy_attributes.assert_called_once_with(source, target, extension)
def test_flatten_enumeration_unions(self, mock_find_class): enum_a = ClassFactory.enumeration(2) enum_b = ClassFactory.enumeration(3) mock_find_class.return_value = enum_b obj = ClassFactory.create( type=SimpleType, attrs=[ AttrFactory.create( name="value", types=[ AttrTypeFactory.create(name=enum_a.name, forward_ref=True), AttrTypeFactory.create(name=enum_b.name), ], ) ], inner=[enum_a], ) self.assertFalse(obj.is_enumeration) self.analyzer.flatten_enumeration_unions(obj) self.assertTrue(obj.is_enumeration) self.assertEqual(5, len(obj.attrs)) self.assertEqual( ["attr_B", "attr_C", "attr_D", "attr_E", "attr_F"], [attr.name for attr in obj.attrs], )