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_children_extensions(self): complex_type = ComplexType.create( attributes=[Attribute.create(index=i) for i in range(2)], simple_content=SimpleContent.create( restriction=Restriction.create(base="bk:b", index=4) ), complex_content=ComplexContent.create( extension=Extension.create(base="bk:ext", index=7) ), ) item = ClassFactory.create() children = self.builder.children_extensions(complex_type, item) expected = list( map( ExtensionFactory.create, [ AttrTypeFactory.create(name="bk:b", index=4), AttrTypeFactory.create(name="bk:ext", index=7), ], ) ) self.assertIsInstance(children, GeneratorType) self.assertEqual(expected, list(children))
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_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_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], )
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_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_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_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_flatten_attribute_types_ignores_forward_types( self, mock_flatten_attribute_type): parent = ClassFactory.create() type_a = AttrTypeFactory.create() type_b = AttrTypeFactory.create(forward_ref=True) attr = AttrFactory.create(name="a", types=[type_a, type_b]) self.analyzer.flatten_attribute_types(parent, attr) mock_flatten_attribute_type.assert_called_once_with( parent, attr, type_a)
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_attribute_display_type(self): parents = [] type_foo_bar = AttrTypeFactory.create(name="foo_bar") attr = AttrFactory.create(name="foo", default="foo", types=[type_foo_bar]) actual = generator.attribute_display_type(attr, parents) self.assertEqual("FooBar", actual) attr.default = None actual = generator.attribute_display_type(attr, parents) self.assertEqual("Optional[FooBar]", actual) parents = ["Parent"] attr.types[0].self_ref = True actual = generator.attribute_display_type(attr, parents) self.assertEqual('Optional["FooBar"]', actual) attr.types[0].forward_ref = True actual = generator.attribute_display_type(attr, parents) self.assertEqual('Optional["Parent.FooBar"]', actual) parents = ["A", "Parent"] attr.restrictions.max_occurs = 2 actual = generator.attribute_display_type(attr, parents) self.assertEqual('List["A.Parent.FooBar"]', actual) attr.types[0].alias = "Boss:Life" actual = generator.attribute_display_type(attr, parents) self.assertEqual('List["A.Parent.BossLife"]', actual) attr.types = [ AttrTypeFactory.create(name="thug:life", alias="Boss:Life", forward_ref=True), AttrTypeFactory.xs_int(), ] actual = generator.attribute_display_type(attr, parents) self.assertEqual('List[Union["A.Parent.BossLife", int]]', actual) attr.restrictions.max_occurs = 1 attr.types = [AttrTypeFactory.xs_qmap()] actual = generator.attribute_display_type(attr, parents) self.assertEqual("Dict[QName, str]", actual) attr.types = [ AttrTypeFactory.xs_int(), AttrTypeFactory.xs_positive_int() ] actual = generator.attribute_display_type(attr, parents) self.assertEqual("Optional[int]", actual)
def test_merge_redefined_classes_copies_attributes(self, mock_copy_attributes): class_a = ClassFactory.create() class_b = ClassFactory.create() class_c = class_a.clone() ext_a = ExtensionFactory.create(type=AttrTypeFactory.create(name=class_a.name)) ext_str = ExtensionFactory.create(type=AttrTypeFactory.create(name="foo")) class_c.extensions.append(ext_a) class_c.extensions.append(ext_str) classes = [class_a, class_b, class_c] self.analyzer.merge_redefined_classes(classes) self.assertEqual(2, len(classes)) mock_copy_attributes.assert_called_once_with(class_a, class_c, ext_a)
def test_clone_attribute(self): attr = AttrFactory.create( restrictions=Restrictions(length=1), types=[ AttrTypeFactory.create(qname="x"), AttrTypeFactory.create(qname="y"), AttrTypeFactory.xs_int(), ], ) restrictions = Restrictions(length=2) clone = ClassUtils.clone_attribute(attr, restrictions) self.assertEqual(2, clone.restrictions.length) self.assertIsNot(attr, clone)
def test_merge_redefined_type_with_circular_extension( self, mock_copy_attributes, mock_copy_extensions ): source = ClassFactory.create() target = source.clone() ext_a = ExtensionFactory.create(type=AttrTypeFactory.create(qname=source.name)) ext_str = ExtensionFactory.create(type=AttrTypeFactory.create(qname="foo")) target.extensions.append(ext_str) target.extensions.append(ext_a) self.validator.merge_redefined_type(source, target) mock_copy_attributes.assert_called_once_with(source, target, ext_a) mock_copy_extensions.assert_called_once_with(source, target, ext_a)
def test_type_name(self): type_str = AttrTypeFactory.xs_string() self.assertEqual("str", generator.type_name(type_str)) type_foo_bar_bam = AttrTypeFactory.create(name="foo:bar_bam") self.assertEqual("BarBam", generator.type_name(type_foo_bar_bam))
def test_copy_attributes(self, mock_clone_attribute, mock_copy_inner_classes): mock_clone_attribute.side_effect = lambda x, y, z: x.clone() target = ClassFactory.create(attrs=[ AttrFactory.create(name="foo:a"), AttrFactory.create(name="b") ]) source = ClassFactory.create(attrs=[ AttrFactory.create(name="c", index=sys.maxsize), AttrFactory.create(name="a"), AttrFactory.create(name="boo:b"), AttrFactory.create(name="d"), ]) extension = ExtensionFactory.create(type=AttrTypeFactory.create( name="foo:foo")) target.extensions.append(extension) ClassUtils.copy_attributes(source, target, extension) self.assertEqual(["foo:a", "b", "d", "c"], [attr.name for attr in target.attrs]) mock_copy_inner_classes.assert_called_once_with(source, target) mock_clone_attribute.assert_has_calls([ mock.call(source.attrs[0], extension.restrictions, "foo"), mock.call(source.attrs[3], extension.restrictions, "foo"), ])
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_process_extension_with_dependency_type( self, mock_process_dependency_extension): extension = ExtensionFactory.create(type=AttrTypeFactory.create("foo")) target = ClassFactory.elements(1, extensions=[extension]) self.processor.process_extension(target, extension) mock_process_dependency_extension.assert_called_once_with( target, extension)
def test_flatten_attribute_types_when_attribute_self_reference(self, *args): parent = ClassFactory.create() type_a = AttrTypeFactory.create() attr = AttrFactory.create(name="a", types=[type_a]) self.analyzer.flatten_attribute_types(parent, attr) self.assertEqual([type_a], attr.types) self.assertTrue(type_a.self_ref)
def test_apply_aliases(self): self.resolver.aliases = { build_qname("xsdata", "d"): "IamD", build_qname("xsdata", "a"): "IamA", } type_a = AttrTypeFactory.create(qname="{xsdata}a") type_b = AttrTypeFactory.create(qname="{xsdata}b") type_c = AttrTypeFactory.create(qname="{xsdata}c") type_d = AttrTypeFactory.create(qname="{xsdata}d") obj = ClassFactory.create( qname="a", attrs=[ AttrFactory.create(name="a", types=[type_a]), AttrFactory.create(name="b", types=[type_b]), AttrFactory.create(name="c", types=[type_a, type_d]), ], inner=[ ClassFactory.create( qname="b", attrs=[ AttrFactory.create(name="c", types=[type_c]), AttrFactory.create(name="d", types=[type_d]), ], ) ], ) self.resolver.apply_aliases(obj) self.assertEqual(3, len(obj.attrs)) self.assertEqual(1, len(obj.attrs[0].types)) self.assertEqual(1, len(obj.attrs[1].types)) self.assertEqual(2, len(obj.attrs[2].types)) self.assertEqual("IamA", obj.attrs[0].types[0].alias) self.assertIsNone(obj.attrs[1].types[0].alias) self.assertEqual("IamA", obj.attrs[2].types[0].alias) self.assertEqual("IamD", obj.attrs[2].types[1].alias) self.assertEqual(1, len(obj.inner)) self.assertEqual(2, len(obj.inner[0].attrs)) self.assertEqual(1, len(obj.inner[0].attrs[0].types)) self.assertEqual(1, len(obj.inner[0].attrs[1].types)) self.assertIsNone(obj.inner[0].attrs[0].types[0].alias) self.assertEqual("IamD", obj.inner[0].attrs[1].types[0].alias)
def test_find_attr_simple_type(self): a = ClassFactory.enumeration(1, name="a") b = ClassFactory.elements(1, name="b", abstract=True) c = ClassFactory.elements(1, name="c") type_a = AttrTypeFactory.create(name="a") type_b = AttrTypeFactory.create(name="b") type_c = AttrTypeFactory.create(name="c") self.analyzer.create_class_index([a, b, c]) self.assertIsNone(self.analyzer.find_attr_simple_type( a, type_a)) # Enumeration self.assertIsNone(self.analyzer.find_attr_simple_type( a, type_c)) # Complex self.assertIsNone(self.analyzer.find_attr_simple_type( b, type_b)) # Source is target self.assertEqual(b, self.analyzer.find_attr_simple_type(a, type_b))
def test_process_extension(self, mock_type_name): extension = ExtensionFactory.create(type=AttrTypeFactory.create( name="foobar")) generator.process_extension(extension) mock_type_name.assert_called_once_with(extension.type) self.assertEqual("oof", extension.type.name)
def test_apply_aliases(self): self.resolver.aliases = {QName("d"): "IamD", QName("a"): "IamA"} type_a = AttrTypeFactory.create(name="a") type_b = AttrTypeFactory.create(name="b") type_c = AttrTypeFactory.create(name="c") type_d = AttrTypeFactory.create(name="d") obj = ClassFactory.create( name="a", attrs=[ AttrFactory.create(name="a", types=[type_a]), AttrFactory.create(name="b", types=[type_b]), AttrFactory.create(name="c", types=[type_a, type_d]), ], source_namespace=None, inner=[ ClassFactory.create( name="b", source_namespace=None, attrs=[ AttrFactory.create(name="c", types=[type_c]), AttrFactory.create(name="d", types=[type_d]), ], ) ], ) self.resolver.apply_aliases(obj) self.assertEqual(3, len(obj.attrs)) self.assertEqual(1, len(obj.attrs[0].types)) self.assertEqual(1, len(obj.attrs[1].types)) self.assertEqual(2, len(obj.attrs[2].types)) self.assertEqual("IamA", obj.attrs[0].types[0].alias) self.assertIsNone(obj.attrs[1].types[0].alias) self.assertEqual("IamA", obj.attrs[2].types[0].alias) self.assertEqual("IamD", obj.attrs[2].types[1].alias) self.assertEqual(1, len(obj.inner)) self.assertEqual(2, len(obj.inner[0].attrs)) self.assertEqual(1, len(obj.inner[0].attrs[0].types)) self.assertEqual(1, len(obj.inner[0].attrs[1].types)) self.assertIsNone(obj.inner[0].attrs[0].types[0].alias) self.assertEqual("IamD", obj.inner[0].attrs[1].types[0].alias)
def test_clone_attribute(self): attr = AttrFactory.create( restrictions=RestrictionsFactory.create(length=1), types=[ AttrTypeFactory.create(name="foo:x"), AttrTypeFactory.create(name="y"), AttrTypeFactory.xs_int(), ], ) restrictions = RestrictionsFactory.create(length=2) prefix = "foo" clone = ClassUtils.clone_attribute(attr, restrictions, prefix) self.assertEqual(["foo:x", "foo:y", "integer"], [x.name for x in clone.types]) self.assertEqual(2, clone.restrictions.length) self.assertIsNot(attr, clone)
def test_process_type_with_inner_type(self, mock_process_native_type, mock_process_dependency_type): attr = AttrFactory.create() target = ClassFactory.create() attr_type = AttrTypeFactory.create(forward=True) self.processor.process_type(target, attr, attr_type) self.assertEqual(0, mock_process_native_type.call_count) self.assertEqual(0, mock_process_dependency_type.call_count)
def test_process_type_with_dependency_type(self, mock_process_native_type, mock_process_dependency_type): attr = AttrFactory.create() target = ClassFactory.create() attr_type = AttrTypeFactory.create() self.processor.process_type(target, attr, attr_type) self.assertEqual(0, mock_process_native_type.call_count) mock_process_dependency_type.assert_called_once_with( target, attr, attr_type)
def test_flatten_attribute_types_when_source_is_enumeration(self, mock_find_class): mock_find_class.return_value = ClassFactory.enumeration(1) parent = ClassFactory.create() type_a = AttrTypeFactory.create(name="a") attr = AttrFactory.create(name="a", types=[type_a]) self.analyzer.flatten_attribute_types(parent, attr) self.assertEqual([type_a], attr.types) mock_find_class.assert_called_once_with(parent.source_qname(type_a.name))
def test_find_attr_type(self, mock_find_class): target = ClassFactory.create() type_a = AttrTypeFactory.create() source = ClassFactory.create() mock_find_class.return_value = source actual = self.analyzer.find_attr_type(target, type_a) self.assertEqual(source, actual) mock_find_class.assert_called_once_with( source.source_qname(type_a.name))
def test_build_class_extensions(self, mock_children_extensions): bar_type = AttrTypeFactory.create(qname="bar") foo_type = AttrTypeFactory.create(qname="foo") some_type = AttrTypeFactory.create(qname="{xsdata}something") bar = ExtensionFactory.create(type=bar_type) double = ExtensionFactory.create(type=bar_type) foo = ExtensionFactory.create(type=foo_type) mock_children_extensions.return_value = [bar, double, foo] self_ext = ExtensionFactory.create(type=some_type, restrictions=Restrictions( min_occurs=1, max_occurs=1)) item = ClassFactory.create() element = Element(type="something") SchemaMapper.build_class_extensions(element, item) self.assertEqual(3, len(item.extensions)) self.assertCountEqual([bar, self_ext, foo], item.extensions)