def test_process(self, mock_process_type, mock_filter_types): xs_int = AttrTypeFactory.native(DataType.INT) xs_bool = AttrTypeFactory.native(DataType.BOOLEAN) xs_string = AttrTypeFactory.native(DataType.STRING) mock_filter_types.side_effect = lambda x: x target = ClassFactory.create(attrs=[ AttrFactory.create(types=[xs_int, xs_bool]), AttrFactory.create(types=[xs_string, xs_string]), ]) self.processor.process(target) self.assertEqual(2, len(target.attrs[0].types)) self.assertEqual(2, len(target.attrs[1].types)) mock_filter_types.assert_has_calls([ mock.call(target.attrs[0].types), mock.call(target.attrs[1].types), ]) mock_process_type.assert_has_calls([ mock.call(target, target.attrs[0], xs_int), mock.call(target, target.attrs[0], xs_bool), mock.call(target, target.attrs[1], xs_string), mock.call(target, target.attrs[1], xs_string), ])
def test_field_type_with_native_type(self): attr = AttrFactory.create(types=[ AttrTypeFactory.native(DataType.INT), AttrTypeFactory.native(DataType.POSITIVE_INTEGER), ]) self.assertEqual("Optional[int]", self.filters.field_type(attr, ["a", "b"]))
def test_add_default_attribute(self): xs_string = AttrTypeFactory.native(DataType.STRING) extension = ExtensionFactory.create(xs_string, Restrictions(required=True)) item = ClassFactory.elements(1, extensions=[extension]) ClassExtensionHandler.add_default_attribute(item, extension) expected = AttrFactory.create(name="@value", default=None, types=[xs_string], tag=Tag.EXTENSION) self.assertEqual(2, len(item.attrs)) self.assertEqual(0, len(item.extensions)) self.assertEqual(expected, item.attrs[0]) xs_int = AttrTypeFactory.native(DataType.INT) extension = ExtensionFactory.create(xs_int, Restrictions(tokens=True)) item.extensions.append(extension) ClassExtensionHandler.add_default_attribute(item, extension) expected.types.append(xs_int) expected_restrictions = Restrictions(tokens=True, required=True, min_occurs=1, max_occurs=1) self.assertEqual(2, len(item.attrs)) self.assertEqual(0, len(item.extensions)) self.assertEqual(expected, item.attrs[0]) self.assertEqual(expected_restrictions, item.attrs[0].restrictions)
def test_filter_types(self): xs_string = AttrTypeFactory.native(DataType.STRING) xs_error = AttrTypeFactory.native(DataType.ERROR) xs_any = AttrTypeFactory.native(DataType.ANY_TYPE) types = [ xs_string.clone(), xs_string.clone(), xs_string.clone(), xs_error.clone(), ] actual = self.processor.filter_types(types) self.assertEqual(1, len(actual)) types.append(xs_any) actual = self.processor.filter_types(types) self.assertEqual(1, len(actual)) self.assertEqual(xs_string, actual[0]) actual = self.processor.filter_types([]) self.assertEqual(xs_string, actual[0]) types = [xs_any] actual = self.processor.filter_types(types) self.assertEqual(1, len(actual))
def test_dependencies(self): obj = ClassFactory.create( attrs=[ AttrFactory.create( types=[AttrTypeFactory.native(DataType.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.native(DataType.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.reference( build_qname(Namespace.XS.uri, "foobar")), ExtensionFactory.reference( 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_property_native_types(self): attr = AttrFactory.create(types=[ AttrTypeFactory.create(qname="foo"), AttrTypeFactory.native(DataType.INT), AttrTypeFactory.native(DataType.SHORT), AttrTypeFactory.native(DataType.INTEGER), AttrTypeFactory.native(DataType.FLOAT), ]) self.assertCountEqual([float, int], attr.native_types)
def test_build_class_attribute_types(self, mock_build_inner_classes, mock_attr_types): mock_attr_types.return_value = ["xs:integer", "xs:string"] mock_build_inner_classes.return_value = [] item = ClassFactory.create() attribute = Attribute(default="false") actual = SchemaMapper.build_class_attribute_types(item, attribute) expected = [ AttrTypeFactory.native(DataType.INTEGER), AttrTypeFactory.native(DataType.STRING), ] self.assertEqual(expected, actual)
def test_group_fields(self): target = ClassFactory.create(attrs=AttrFactory.list(2)) target.attrs[0].restrictions.choice = "1" target.attrs[1].restrictions.choice = "1" 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.native(DataType.ANY_TYPE)], 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_process(self): item = ClassFactory.create() self.processor.process(item) self.assertEqual(0, len(item.attrs)) item = ClassFactory.elements(2, mixed=True) self.processor.process(item) expected = AttrFactory.create( name="content", types=[AttrTypeFactory.native(DataType.ANY_TYPE)], tag=Tag.ANY, namespace="##any", ) # Wildcard is not defined self.assertEqual(expected, item.attrs[0]) self.assertTrue(item.attrs[0].is_list) self.assertEqual(3, len(item.attrs)) self.assertTrue(item.attrs[0].mixed) # Wildcard is defined and is list item.attrs[0].restrictions.max_occurs = 3 item.attrs[0].mixed = False self.processor.process(item) self.assertEqual(3, len(item.attrs)) self.assertTrue(item.attrs[0].mixed) self.assertEqual(3, item.attrs[0].restrictions.max_occurs) # Wildcard is defined but not list item.attrs[0].restrictions.max_occurs = 1 self.processor.process(item) self.assertTrue(item.attrs[0].is_list) self.assertEqual(sys.maxsize, item.attrs[0].restrictions.max_occurs)
def test_build_class_attribute_from_list(self): target = ClassFactory.create() data = [1, True, 1.1] DictMapper.build_class_attribute(target, "a", data) expected = AttrFactory.create( name="a", tag=Tag.ELEMENT, types=[ AttrTypeFactory.native(DataType.SHORT, tag=Tag.ELEMENT), AttrTypeFactory.native(DataType.BOOLEAN, tag=Tag.ELEMENT), AttrTypeFactory.native(DataType.FLOAT, tag=Tag.ELEMENT), ], ) restrictions = Restrictions(max_occurs=sys.maxsize) self.assertEqual(expected, target.attrs[0]) self.assertEqual(restrictions, target.attrs[0].restrictions)
def test_process_type_with_native_type(self, mock_process_native_type, mock_process_dependency_type): attr = AttrFactory.create() target = ClassFactory.create() xs_int = AttrTypeFactory.native(DataType.INT) self.processor.process_type(target, attr, xs_int) self.assertEqual(0, mock_process_dependency_type.call_count) mock_process_native_type.assert_called_once_with(attr, xs_int)
def test_build_class_attribute_types_when_obj_has_inner_class( self, mock_build_inner_classes, mock_attr_types): inner_class = ClassFactory.create(qname="foo") mock_attr_types.return_value = ["xs:integer", "xs:string"] mock_build_inner_classes.return_value = [inner_class] item = ClassFactory.create() attribute = Attribute(default="false") actual = SchemaMapper.build_class_attribute_types(item, attribute) expected = [ AttrTypeFactory.native(DataType.INTEGER), AttrTypeFactory.native(DataType.STRING), AttrTypeFactory.create(qname=inner_class.qname, forward=True), ] self.assertEqual(expected, actual) self.assertEqual([inner_class], item.inner)
def test_field_metadata_restrictions(self): attr = AttrFactory.create(tag=Tag.RESTRICTION) attr.types.append(AttrTypeFactory.native(DataType.INT)) attr.restrictions.min_occurs = 1 attr.restrictions.max_occurs = 2 attr.restrictions.max_inclusive = "2" attr.restrictions.required = False expected = {"min_occurs": 1, "max_occurs": 2, "max_inclusive": 2} self.assertEqual(expected, self.filters.field_metadata(attr, None, []))
def test_constant_value(self): attr = AttrFactory.create( types=[AttrTypeFactory.native(DataType.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_field_type_with_multiple_types(self): attr = AttrFactory.create(types=[ AttrTypeFactory.create( qname="life", alias="Boss:Life", forward=True), AttrTypeFactory.native(DataType.INT), ]) attr.restrictions.max_occurs = 2 self.assertEqual( 'List[Union["A.Parent.BossLife", int]]', self.filters.field_type(attr, ["A", "Parent"]), )
def test_build_class_attribute_types_when_obj_has_no_types( self, mock_build_inner_classes, mock_attr_types, mock_default_type): mock_attr_types.return_value = "" mock_build_inner_classes.return_value = [] mock_default_type.return_value = "xs:string" item = ClassFactory.create() attribute = Attribute(default="false", name="attr") actual = SchemaMapper.build_class_attribute_types(item, attribute) self.assertEqual(1, len(actual)) self.assertEqual(AttrTypeFactory.native(DataType.STRING), actual[0])
def test_process_native_type(self): attr = AttrFactory.native(DataType.INT) nm_tokens_type = AttrTypeFactory.native(DataType.NMTOKENS) self.processor.process_native_type(attr, attr.types[0]) self.assertEqual(str(DataType.INT), attr.types[0].qname) attr.restrictions.pattern = "[a-z]" self.processor.process_native_type(attr, attr.types[0]) self.assertEqual(str(DataType.STRING), attr.types[0].qname) self.processor.process_native_type(attr, nm_tokens_type) self.assertTrue(attr.restrictions.tokens)
def test_clone_attribute(self): attr = AttrFactory.create( restrictions=Restrictions(length=1), types=[ AttrTypeFactory.create(qname="x"), AttrTypeFactory.create(qname="y"), AttrTypeFactory.native(DataType.INT), ], ) restrictions = Restrictions(length=2) clone = ClassUtils.clone_attribute(attr, restrictions) self.assertEqual(2, clone.restrictions.length) self.assertIsNot(attr, clone)
def test_should_flatten_extension(self): source = ClassFactory.create() target = ClassFactory.create() self.assertFalse(self.processor.should_flatten_extension(source, target)) # Source has suffix attr and target has its own attrs source = ClassFactory.elements(1) source.attrs[0].index = sys.maxsize target.attrs.append(AttrFactory.create()) self.assertTrue(self.processor.should_flatten_extension(source, target)) # Target has suffix attr source = ClassFactory.create() target = ClassFactory.elements(1) target.attrs[0].index = sys.maxsize self.assertTrue(self.processor.should_flatten_extension(source, target)) # Source is a simple type source = ClassFactory.create(attrs=[AttrFactory.create(tag=Tag.SIMPLE_TYPE)]) target = ClassFactory.elements(1) self.assertTrue(self.processor.should_flatten_extension(source, target)) # Sequential violation source = ClassFactory.elements(3) target = source.clone() self.assertFalse(self.processor.should_flatten_extension(source, target)) for attr in target.attrs: attr.restrictions.sequential = True self.assertFalse(self.processor.should_flatten_extension(source, target)) target.attrs = [target.attrs[1], target.attrs[0], target.attrs[2]] self.assertTrue(self.processor.should_flatten_extension(source, target)) # Types violation target = source.clone() target.attrs[1].types = [ AttrTypeFactory.native(DataType.INT), AttrTypeFactory.native(DataType.FLOAT), ] source.attrs[1].types = [ AttrTypeFactory.native(DataType.INT), AttrTypeFactory.native(DataType.FLOAT), AttrTypeFactory.native(DataType.DECIMAL), ] self.assertFalse(self.processor.should_flatten_extension(source, target)) target.attrs[1].types.append(AttrTypeFactory.native(DataType.QNAME)) self.assertTrue(self.processor.should_flatten_extension(source, target))
def test_add_default_attribute_with_any_type(self): extension = ExtensionFactory.create( AttrTypeFactory.native(DataType.ANY_TYPE), Restrictions(min_occurs=1, max_occurs=1, required=True), ) item = ClassFactory.create(extensions=[extension]) ClassExtensionHandler.add_default_attribute(item, extension) expected = AttrFactory.create( name="@any_element", 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_process_enum_extension_with_simple_source(self): qname_type = AttrTypeFactory.native(DataType.QNAME) source = ClassFactory.create( tag=Tag.SIMPLE_TYPE, attrs=[ AttrFactory.create(types=[qname_type], restrictions=Restrictions(length=10)) ], ) target = ClassFactory.enumeration(2) extension = ExtensionFactory.reference(source.qname) target.extensions.append(extension) self.processor.container.add(source) self.processor.container.add(target) self.processor.process_dependency_extension(target, extension) for attr in target.attrs: self.assertIn(qname_type, attr.types) self.assertEqual(10, attr.restrictions.length)
from xsdata.codegen.models import Restrictions from xsdata.formats.dataclass.filters import Filters from xsdata.models.config import DocstringStyle from xsdata.models.config import GeneratorAlias from xsdata.models.config import GeneratorConfig from xsdata.models.config import NameCase from xsdata.models.enums import DataType from xsdata.models.enums import Namespace from xsdata.models.enums import Tag from xsdata.utils.testing import AttrFactory from xsdata.utils.testing import AttrTypeFactory from xsdata.utils.testing import FactoryTestCase type_str = AttrTypeFactory.native(DataType.STRING) type_int = AttrTypeFactory.native(DataType.INT) type_float = AttrTypeFactory.native(DataType.FLOAT) type_decimal = AttrTypeFactory.native(DataType.DECIMAL) type_bool = AttrTypeFactory.native(DataType.BOOLEAN) type_qname = AttrTypeFactory.native(DataType.QNAME) type_tokens = AttrTypeFactory.native(DataType.NMTOKENS) type_datetime = AttrTypeFactory.native(DataType.DATE_TIME) type_duration = AttrTypeFactory.native(DataType.DURATION) class FiltersTests(FactoryTestCase): def setUp(self) -> None: super().setUp() self.filters = Filters() def test_class_name(self): self.filters.class_aliases["boom"] = "Bang"
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]), AttrFactory.create( name="compound", types=[AttrTypeFactory.native(DataType.ANY_TYPE)], choices=[ AttrFactory.create(name="a", types=[type_a, type_d]), ], ), ], ) ], extensions=[ExtensionFactory.create(type_a)], ) 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("IamA", obj.extensions[0].type.alias) self.assertEqual(1, len(obj.inner)) self.assertEqual(3, 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.assertEqual("IamA", obj.inner[0].attrs[2].choices[0].types[0].alias) self.assertEqual("IamD", obj.inner[0].attrs[2].choices[0].types[1].alias) self.assertIsNone(obj.inner[0].attrs[0].types[0].alias) self.assertEqual("IamD", obj.inner[0].attrs[1].types[0].alias)
def test_flatten_skip_when_types_is_not_enumeration_union(self): self.target.attrs[0].types.append(AttrTypeFactory.native(DataType.INT)) self.processor.process(self.target) self.assertFalse(self.target.is_enumeration)