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_flatten_extension_simple_when_source_and_target_are_enumerations( self, mock_copy_attributes): source = ClassFactory.enumeration(2) target = ClassFactory.enumeration(1) extension = ExtensionFactory.create() self.analyzer.flatten_extension_simple(source, target, extension) mock_copy_attributes.assert_called_once_with(source, target, extension)
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_filter_classes_with_only_simple_types(self, mock_class_should_generate): mock_class_should_generate.return_value = False classes = [ClassFactory.enumeration(2), ClassFactory.create(type=SimpleType)] container = ClassContainer.from_list(classes) container.filter_classes() self.assertEqual(classes, container.class_list)
def test_process_native_extension_with_enumeration_target( self, mock_copy_extension_type): extension = ExtensionFactory.create() target = ClassFactory.enumeration(1) self.processor.process_native_extension(target, extension) mock_copy_extension_type.assert_called_once_with(target, extension)
def test_flatten_extension_native_and_target_enumeration( self, mock_create_default_attribute): extension = ExtensionFactory.create() target = ClassFactory.enumeration(1) self.analyzer.flatten_extension_native(target, extension) self.assertEqual(0, mock_create_default_attribute.call_count)
def test_render_module(self): classes = [ ClassFactory.enumeration(2, help="\n\nI am enum "), ClassFactory.elements(2), ClassFactory.service(2), ] classes[0].attrs[0].help = "I am a member" classes[1].attrs[0].help = "I am a field" resolver = DependenciesResolver() actual = self.generator.render_module(resolver, classes) expected = ("from dataclasses import dataclass, field\n" "from enum import Enum\n" "from typing import Optional\n" "\n" '__NAMESPACE__ = "xsdata"\n' "\n" "\n" "class ClassB(Enum):\n" ' """\n' " I am enum.\n" "\n" " :cvar ATTR_B: I am a member\n" " :cvar ATTR_C:\n" ' """\n' " ATTR_B = None\n" " ATTR_C = None\n" "\n" "\n" "@dataclass\n" "class ClassC:\n" ' """\n' " :ivar attr_d: I am a field\n" " :ivar attr_e:\n" ' """\n' " class Meta:\n" ' name = "class_C"\n' "\n" " attr_d: Optional[str] = field(\n" " default=None,\n" " metadata={\n" ' "name": "attr_D",\n' ' "type": "Element",\n' " }\n" " )\n" " attr_e: Optional[str] = field(\n" " default=None,\n" " metadata={\n" ' "name": "attr_E",\n' ' "type": "Element",\n' " }\n" " )\n" "\n" "\n" "class ClassD:\n" ' attr_f = "None"\n' ' attr_g = "None"\n') self.assertEqual(expected, actual)
def test_select_classes_when_no_complex_class_available(self): classes = [ ClassFactory.enumeration(2), ClassFactory.create(type=SimpleType) ] container = ClassContainer.from_list(classes) self.assertEqual(classes, ClassAnalyzer.select_classes(container))
def test_class_docstring_with_enumeration(self): target = ClassFactory.enumeration(2, help="Help Me!") expected = '''"""Help Me! :cvar ATTR_B: :cvar ATTR_C: """''' self.assertEqual(expected, class_docstring(target, enum=True))
def test_flatten_extension_simple_when_source_is_enumeration_and_target_is_not( self, mock_create_default_attribute ): source = ClassFactory.enumeration(2) target = ClassFactory.elements(1) extension = ExtensionFactory.create() self.analyzer.flatten_extension_simple(source, target, extension) mock_create_default_attribute.assert_called_once_with(target, extension)
def test_property_is_enumeration(self): obj = ClassFactory.enumeration(2) self.assertTrue(obj.is_enumeration) obj.attrs.append(AttrFactory.element()) self.assertFalse(obj.is_enumeration) obj.attrs.clear() self.assertFalse(obj.is_enumeration)
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_process_simple_dependency_with_enumeration(self): source = ClassFactory.enumeration(2) target = ClassFactory.create() attr = AttrFactory.create() attr_type = attr.types[0] expected = attr_type.clone() self.processor.process_simple_dependency(source, target, attr, attr_type) self.assertEqual(expected, attr_type)
def test_flatten_extension_simple_when_target_is_enumeration_and_source_is_not( self, mock_create_default_attribute, mock_copy_attributes): extension = ExtensionFactory.create() source = ClassFactory.elements(2) target = ClassFactory.enumeration(1, extensions=[extension]) self.analyzer.flatten_extension_simple(source, target, extension) self.assertEqual(0, mock_create_default_attribute.call_count) self.assertEqual(0, mock_copy_attributes.call_count) self.assertEqual(0, len(target.extensions))
def setUp(self): super().setUp() self.root_enum = ClassFactory.enumeration(2) self.inner_enum = ClassFactory.enumeration(2) self.target = ClassFactory.create(attrs=[ AttrFactory.create( name="value", tag=Tag.UNION, types=[ AttrTypeFactory.create(name=self.root_enum.name), AttrTypeFactory.create(name=self.inner_enum.name, forward=True), ], ), ], ) self.target.inner.append(self.inner_enum) container = ClassContainer.from_list([self.target, self.root_enum]) self.processor = AttributeEnumUnionHandler(container=container)
def test_find_simple_class(self): a = ClassFactory.enumeration(1, name="a") b = ClassFactory.create(name="b", type=SimpleType) c = ClassFactory.elements(1, name="c", abstract=True) d = ClassFactory.elements(1, name="d") self.analyzer.create_class_index([a, b, c, d]) self.assertEqual(a, self.analyzer.find_simple_class(a.source_qname())) self.assertEqual(b, self.analyzer.find_simple_class(b.source_qname())) self.assertEqual(c, self.analyzer.find_simple_class(c.source_qname())) self.assertIsNone(self.analyzer.find_simple_class(d.source_qname()))
def test_build_inner_classes_with_enumeration(self, mock_build_class): inner = ClassFactory.enumeration(2) mock_build_class.return_value = inner enumeration = SimpleType.create( restriction=Restriction.create(enumerations=[Enumeration.create(value="a")]) ) result = self.builder.build_inner_classes(enumeration) self.assertIsInstance(result, Iterator) self.assertEqual([inner], list(result)) self.assertIsNone(enumeration.name)
def test_find_inner(self, mock_process_class): obj = ClassFactory.create() first = ClassFactory.create(qname="{a}a") second = ClassFactory.enumeration(2, qname="{a}a") third = ClassFactory.create(qname="{c}c", status=Status.PROCESSED) fourth = ClassFactory.enumeration(2, qname="{d}d", status=Status.PROCESSING) obj.inner.extend((first, second, third, fourth)) def process_class(x: Class): x.status = Status.PROCESSED def is_enum(x: Class): return x.is_enumeration mock_process_class.side_effect = process_class self.assertIsNone(self.container.find_inner(obj, "nope")) self.assertEqual(first, self.container.find_inner(obj, "a")) self.assertEqual(second, self.container.find_inner(obj, "a", is_enum)) self.assertEqual(third, self.container.find_inner(obj, "c")) self.assertEqual(fourth, self.container.find_inner(obj, "d", is_enum)) mock_process_class.assert_has_calls([mock.call(first), mock.call(second)])
def test_find_enum(self): native_type = AttrTypeFactory.create() matching_external = AttrTypeFactory.create("foo") missing_external = AttrTypeFactory.create("bar") matching_inner = AttrTypeFactory.create("foobar", forward=True) missing_inner = AttrTypeFactory.create("barfoo", forward=True) 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, matching_inner, missing_inner, ] ) ], inner=[inner], ) self.sanitizer.container.extend([target, enumeration]) actual = self.sanitizer.find_enum(target, native_type) self.assertIsNone(actual) actual = self.sanitizer.find_enum(target, matching_external) self.assertEqual(enumeration, actual) actual = self.sanitizer.find_enum(target, missing_external) self.assertIsNone(actual) actual = self.sanitizer.find_enum(target, matching_inner) self.assertEqual(inner, actual) actual = self.sanitizer.find_enum(target, missing_inner) self.assertIsNone(actual)
def test_build_inner_classes_with_enumeration(self, mock_build_class): inner = ClassFactory.enumeration(2) mock_build_class.return_value = inner enumeration = SimpleType(restriction=Restriction( enumerations=[Enumeration(value="a")])) result = SchemaMapper.build_inner_classes(enumeration, "module", "target_ns") self.assertIsInstance(result, Iterator) self.assertEqual([inner], list(result)) self.assertIsNone(enumeration.name) mock_build_class.assert_called_once_with(enumeration, Tag.SIMPLE_TYPE, "module", "target_ns")
def test_find(self, mock_process_class): def process_class(x: Class): x.status = Status.PROCESSED class_a = ClassFactory.create(qname="a") class_b = ClassFactory.create(qname="b", status=Status.PROCESSED) class_c = ClassFactory.enumeration(2, qname="b", status=Status.PROCESSING) mock_process_class.side_effect = process_class self.container.extend([class_a, class_b, class_c]) self.assertIsNone(self.container.find("nope")) self.assertEqual(class_a, self.container.find(class_a.qname)) self.assertEqual(class_b, self.container.find(class_b.qname)) self.assertEqual( class_c, self.container.find(class_b.qname, lambda x: x.is_enumeration) ) mock_process_class.assert_called_once_with(class_a)
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_find(self, mock_process_class): class_a = ClassFactory.create(name="a") class_b = ClassFactory.create(name="b", status=Status.PROCESSED) class_c = ClassFactory.enumeration(2, name="b", status=Status.PROCESSING) self.container.extend([class_a, class_b, class_c]) self.assertIsNone(self.container.find(QName("nope"))) self.assertEqual(class_a, self.container.find(class_a.source_qname())) self.assertEqual(class_b, self.container.find(class_b.source_qname())) self.assertEqual( class_c, self.container.find(class_b.source_qname(), lambda x: x.is_enumeration), ) mock_process_class.assert_called_once_with(class_a)
def test_find_inner(self): inner_a = ClassFactory.create(qname="a") inner_b = ClassFactory.enumeration(2) target = ClassFactory.create(inner=[inner_a, inner_b]) self.assertEqual( inner_a, self.sanitizer.find_inner(target, condition=lambda x: x.name == "a"), ) self.assertEqual( inner_b, self.sanitizer.find_inner(target, condition=lambda x: x.is_enumeration), ) self.assertIsNone( self.sanitizer.find_inner( target, condition=lambda x: x.name == "a" and x.is_enumeration))
def test_fetch_classes_for_generation(self, mock_sanitize_attributes): classes = [ ClassFactory.create(abstract=True, type=Element), ClassFactory.create(type=Element), ClassFactory.create(type=ComplexType), ClassFactory.create(type=SimpleType), ClassFactory.enumeration(2), ] self.analyzer.create_class_index(classes) expected = [ classes[1], classes[2], classes[4], ] result = self.analyzer.fetch_classes_for_generation() self.assertEqual(expected, result) mock_sanitize_attributes.assert_has_calls([mock.call(x) for x in expected])
def test_select_classes(self, mock_validate_references): classes = [ ClassFactory.create(strict_type=True, type=ComplexType), ClassFactory.create(type=Element), ClassFactory.create(type=ComplexType), ClassFactory.create(type=SimpleType), ClassFactory.enumeration(2), ] container = ClassContainer.from_list(classes) expected = [ classes[1], classes[2], classes[4], ] self.assertEqual(expected, ClassAnalyzer.select_classes(container)) mock_validate_references.assert_called_once_with(expected)
def test_process_class( self, mock_class_name, mock_process_extension, mock_process_attributes, mock_process_enumerations, ): mock_class_name.side_effect = lambda x: f"@{x}" type_o = AttrTypeFactory.create(name="o") type_m = AttrTypeFactory.create(name="m") type_n = AttrTypeFactory.create(name="n") a = ClassFactory.create( name="a", extensions=[type_m, type_n], attrs=AttrFactory.list(2, local_type=TagType.EXTENSION), ) e = ClassFactory.enumeration(2, name="e") i = ClassFactory.create( name="i", extensions=[type_o], attrs=AttrFactory.list(2, local_type=TagType.EXTENSION), ) a.inner = [e, i] generator.process_class(a) mock_class_name.assert_has_calls( [mock.call("a"), mock.call("e"), mock.call("i")]) mock_process_extension.assert_has_calls( [mock.call(type_o), mock.call(type_m), mock.call(type_n)]) mock_process_attributes.assert_has_calls( [mock.call(i, ["@a", "@i"]), mock.call(a, ["@a"])]) mock_process_enumerations.assert_called_once_with(e)
def test_process(self): target = ClassFactory.elements(2) self.processor.process(target) self.assertEqual(2, len(target.attrs)) self.assertEqual(0, len(target.inner)) target = ClassFactory.enumeration(2) self.processor.process(target) self.assertEqual(2, len(target.attrs)) self.assertEqual(0, len(target.inner)) enumerations = list(target.attrs) target.attrs.append(AttrFactory.element()) self.processor.process(target) self.assertEqual(1, len(target.attrs)) self.assertEqual(1, len(target.inner)) self.assertEqual(enumerations, target.inner[0].attrs) target.attrs.append(AttrFactory.enumeration()) self.processor.process(target) self.assertEqual(1, len(target.attrs)) self.assertEqual(1, len(target.inner)) self.assertEqual(3, len(target.inner[0].attrs)) target.attrs.append(AttrFactory.element()) self.processor.process(target) self.assertEqual(2, len(target.attrs)) self.assertEqual(1, len(target.inner)) self.assertEqual(3, len(target.inner[0].attrs)) target.attrs.append(AttrFactory.enumeration()) with self.assertRaises(AnalyzerValueError) as cm: self.processor.process(target) self.assertEqual("Mixed enumeration with more than one normal field.", str(cm.exception))
def test_render_module(self): classes = [ClassFactory.enumeration(2), ClassFactory.elements(2)] resolver = DependenciesResolver() actual = DataclassGenerator().render_module(resolver, classes) expected = ( "from enum import Enum\n" "from dataclasses import dataclass, field\n" "from typing import Optional\n\n" '__NAMESPACE__ = "xsdata"\n\n\n' "class ClassB(Enum):\n" ' """\n' " :cvar NONE_VALUE:\n" ' """\n' " NONE_VALUE = None\n\n\n" "@dataclass\n" "class ClassC:\n" ' """\n' " :ivar attr_d:\n" " :ivar attr_e:\n" ' """\n' " class Meta:\n" ' name = "class_C"\n\n' " attr_d: Optional[str] = field(\n" " default=None,\n" " metadata=dict(\n" ' name="attr_D",\n' ' type="Element"\n' " )\n" " )\n" " attr_e: Optional[str] = field(\n" " default=None,\n" " metadata=dict(\n" ' name="attr_E",\n' ' type="Element"\n' " )\n" " )\n" ) self.assertEqual(expected, actual)
def test_property_should_generate(self): obj = ClassFactory.create(type=xsd.Element) self.assertTrue(obj.should_generate) obj = ClassFactory.create(type=xsd.ComplexType) self.assertTrue(obj.should_generate) obj.attrs.append(AttrFactory.create(tag=Tag.EXTENSION)) self.assertFalse(obj.should_generate) obj = ClassFactory.create(type=wsdl.BindingOperation) self.assertTrue(obj.should_generate) obj = ClassFactory.create(type=wsdl.BindingMessage) self.assertTrue(obj.should_generate) obj = ClassFactory.enumeration(2) self.assertTrue(obj.should_generate) obj = ClassFactory.create(type=xsd.SimpleType) self.assertFalse(obj.should_generate) obj = ClassFactory.create(type=wsdl.BindingMessage, strict_type=True) self.assertFalse(obj.should_generate)