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_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_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_copy_attribute_properties(self, mock_copy_inner_class): source = ClassFactory.elements(1, qname="Foobar") source.attrs[0].restrictions.max_length = 100 source.attrs[0].restrictions.min_length = 1 source.attrs[0].help = "foo" source.attrs[0].types = [ AttrTypeFactory.create(qname="first"), AttrTypeFactory.create(qname="second"), ] target = ClassFactory.elements(1) attr = target.attrs[0] attr.restrictions.min_length = 2 attr.types.clear() attr.types.append(AttrTypeFactory.create(qname=source.name)) self.assertEqual("Foobar", attr.types[0].name) self.processor.copy_attribute_properties(source, target, attr, attr.types[0]) self.assertEqual("first", attr.types[0].name) self.assertEqual("second", attr.types[1].name) self.assertEqual("foo", attr.help) self.assertEqual(Restrictions(min_length=2, max_length=100), attr.restrictions) mock_copy_inner_class.assert_has_calls([ mock.call(source, target, attr, source.attrs[0].types[0]), mock.call(source, target, attr, source.attrs[0].types[1]), ])
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_find_enum(self): native_type = AttrTypeFactory.create() matching_external = AttrTypeFactory.create("foo") missing_external = AttrTypeFactory.create("bar") enumeration = ClassFactory.enumeration(1, qname="foo") inner = ClassFactory.enumeration(1, qname="foobar") target = ClassFactory.create( attrs=[ AttrFactory.create(types=[ native_type, matching_external, missing_external, ]) ], inner=[inner], ) self.sanitizer.container.extend([target, enumeration]) actual = self.sanitizer.find_enum(native_type) self.assertIsNone(actual) actual = self.sanitizer.find_enum(matching_external) self.assertEqual(enumeration, actual) actual = self.sanitizer.find_enum(missing_external) self.assertIsNone(actual)
def test_rename_class_dependencies(self): attr_type = AttrTypeFactory.create("{foo}bar") target = ClassFactory.create( extensions=[ ExtensionFactory.create(), ExtensionFactory.create(attr_type.clone()), ], attrs=[ AttrFactory.create(), AttrFactory.create( types=[AttrTypeFactory.create(), attr_type.clone()]), ], inner=[ ClassFactory.create( extensions=[ExtensionFactory.create(attr_type.clone())], attrs=[ AttrFactory.create(), AttrFactory.create(types=[ AttrTypeFactory.create(), attr_type.clone() ]), ], ) ], ) self.sanitizer.rename_class_dependencies(target, "{foo}bar", "thug") dependencies = set(target.dependencies()) self.assertNotIn("{foo}bar", dependencies) self.assertIn("thug", dependencies)
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_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_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_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_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_process_attribute_default_enum(self, mock_find_enum, mock_logger_warning): enum_one = ClassFactory.enumeration(1, qname="{a}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@{a}root::one", "@enum@inner::two", None], actual) 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_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_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_process_type_with_forward_reference(self, mock_process_inner_type): attr = AttrFactory.create() target = ClassFactory.create() attr_type = AttrTypeFactory.create(forward=True) self.processor.process_type(target, attr, attr_type) mock_process_inner_type.assert_called_once_with(target, attr, attr_type)
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_copy_attributes(self, mock_clone_attribute, mock_copy_inner_classes): mock_clone_attribute.side_effect = lambda x, y: x.clone() target = ClassFactory.create( attrs=[AttrFactory.create(name="a"), AttrFactory.create(name="b")] ) source = ClassFactory.create( attrs=[ AttrFactory.create(name="c", index=sys.maxsize), AttrFactory.create(name="a"), AttrFactory.create(name="b"), AttrFactory.create(name="d"), ] ) extension = ExtensionFactory.create(AttrTypeFactory.create(qname="foo")) target.extensions.append(extension) ClassUtils.copy_attributes(source, target, extension) self.assertEqual(["a", "b", "d", "c"], [attr.name for attr in target.attrs]) mock_copy_inner_classes.assert_has_calls( [ mock.call(source, target, source.attrs[0]), mock.call(source, target, source.attrs[3]), ] ) mock_clone_attribute.assert_has_calls( [ mock.call(source.attrs[0], extension.restrictions), mock.call(source.attrs[3], extension.restrictions), ] )
def test_field_type_with_forward_reference(self): attr = AttrFactory.create( types=AttrTypeFactory.list(1, qname="foo_bar", forward=True)) self.assertEqual( 'Optional["Parent.Inner.FooBar"]', self.filters.field_type(attr, ["Parent", "Inner"]), )
def test_promote(self): target = ClassFactory.elements(2) inner = ClassFactory.enumeration(3) target.inner.append(inner) target.inner.append(ClassFactory.simple_type()) # Irrelevant attr_type = AttrTypeFactory.create(qname=inner.qname, forward=True) target.attrs[0].types.append(attr_type.clone()) target.attrs[1].types.append(attr_type.clone()) self.container.add(target) self.assertEqual(3, len(self.container.data)) self.processor.process(target) new_qname = build_qname(inner.target_namespace, f"{target.name}_{inner.name}") self.assertEqual(4, len(self.container.data)) new_inner = self.container.find(new_qname) self.assertEqual(1, len(target.inner)) self.assertNotEqual(new_inner.qname, inner.qname) self.assertEqual(new_inner.attrs, inner.attrs) self.assertEqual(new_inner.qname, target.attrs[0].types[1].qname) self.assertEqual(new_inner.qname, target.attrs[1].types[1].qname) self.assertFalse(target.attrs[0].types[1].forward) self.assertFalse(target.attrs[1].types[1].forward)
def test_build_class_attribute_from_dict(self): target = ClassFactory.create() data = {"sub1": 1, "sub2": "value"} DictMapper.build_class_attribute(target, "a", data) expected = AttrFactory.create( name="a", tag=Tag.ELEMENT, types=[AttrTypeFactory.create(qname="a", forward=True)], ) expected_inner = ClassFactory.create( qname="a", tag=Tag.ELEMENT, module="", ns_map={}, attrs=[ AttrFactory.native(DataType.SHORT, name="sub1"), AttrFactory.native(DataType.STRING, name="sub2"), ], ) self.assertEqual(expected, target.attrs[0]) self.assertEqual(expected_inner, target.inner[0]) self.assertEqual(1, len(target.inner))
def test_process_extension_with_dependency_type( self, mock_process_dependency_extension): extension = ExtensionFactory.create(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_reset_unsupported_types_ignore_user_types(self): attr_type = AttrTypeFactory.create(qname="foo") attr = AttrFactory.create(types=[attr_type], fixed=True, default="123") target = ClassFactory.create() target.attrs.append(attr) self.processor.process(target) self.assertEqual(attr_type, attr.types[0])
def test_field_type_with_alias(self): attr = AttrFactory.create(types=AttrTypeFactory.list( 1, qname="foo_bar", forward=True, alias="Boss:Life")) attr.restrictions.max_occurs = 2 self.assertEqual( 'List["A.Parent.BossLife"]', self.filters.field_type(attr, ["A", "Parent"]), )
def test_copy_inner_class_with_missing_inner(self): source = ClassFactory.create() target = ClassFactory.create() attr = AttrFactory.create() attr_type = AttrTypeFactory.create(forward=True, qname=target.qname) with self.assertRaises(CodeGenerationError): ClassUtils.copy_inner_class(source, target, attr, attr_type)
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_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_process_inner_type_with_circular_reference( self, mock_copy_attribute_properties, mock_update_restrictions): target = ClassFactory.create() attr = AttrFactory.create() attr_type = AttrTypeFactory.create(circular=True) self.processor.process_inner_type(target, attr, attr_type) self.assertEqual(0, mock_copy_attribute_properties.call_count) self.assertEqual(0, mock_update_restrictions.call_count)