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_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_create_substitutions(self, mock_create_substitution): ns = "xsdata" classes = [ ClassFactory.create( substitutions=[build_qname(ns, "foo"), build_qname(ns, "bar")], abstract=True, ), ClassFactory.create(substitutions=[build_qname(ns, "foo")], abstract=True), ] reference_attrs = AttrFactory.list(3) mock_create_substitution.side_effect = reference_attrs self.processor.container.extend(classes) self.processor.create_substitutions() expected = { build_qname(ns, "foo"): [reference_attrs[0], reference_attrs[2]], build_qname(ns, "bar"): [reference_attrs[1]], } self.assertEqual(expected, self.processor.substitutions) mock_create_substitution.assert_has_calls( [mock.call(classes[0]), mock.call(classes[0]), mock.call(classes[1])] )
def test_get_or_create_inner_class(self): target = ClassFactory.create(module="foo", package=None, ns_map={"foo": "bar"}) actual = DefinitionsMapper.build_inner_class(target, "body") expected = ClassFactory.create( qname="body", tag=Tag.BINDING_MESSAGE, module=target.module, package=None, ns_map=target.ns_map, ) self.assertEqual(expected, actual) self.assertIn(actual, target.inner) self.assertIsNot(actual.ns_map, target.ns_map) expected_attr = DefinitionsMapper.build_attr("body", "body", forward=True) self.assertEqual(expected_attr, target.attrs[0]) repeat = DefinitionsMapper.build_inner_class(target, "body") self.assertIs(repeat, actual)
def test_map_binding_operation_messages_with_style_rpc( self, mock_build_envelope_class, mock_build_message_class): definitions = Definitions() operation = BindingOperation() port_operation = PortTypeOperation() name = "Add" namespace = "someNS" target = ClassFactory.create() message = ClassFactory.create() style = "rpc" mock_build_message_class.return_value = message mock_build_envelope_class.return_value = target operation.input = BindingMessage() port_operation.input = PortTypeMessage() result = DefinitionsMapper.map_binding_operation_messages( definitions, operation, port_operation, name, style, namespace) self.maxDiff = None self.assertEqual([message, target], list(result)) mock_build_message_class.assert_called_once_with( definitions, port_operation.input) mock_build_envelope_class.assert_called_once_with( definitions, operation.input, port_operation.input, f"{name}_input", style, namespace, )
def test_build_envelope_fault(self): body = ClassFactory.create(qname="Body") target = ClassFactory.create() target.inner.append(body) port_type_operation = PortTypeOperation() definitions = Definitions() DefinitionsMapper.build_envelope_fault(definitions, port_type_operation, target) expected_fault_attr = DefinitionsMapper.build_attr( "Fault", body.inner[0].qname, forward=True, namespace=target.namespace) str_qname = str(DataType.STRING) expected_fault_attrs = [ DefinitionsMapper.build_attr(name, str_qname, native=True, namespace="") for name in ["faultcode", "faultstring", "faultactor", "detail"] ] self.assertEqual(1, len(body.attrs)) self.assertEqual(expected_fault_attr, body.attrs[0]) self.assertEqual(expected_fault_attrs, body.inner[0].attrs)
def test_render_package(self): classes = [ ClassFactory.create(qname="a", package="foo"), ClassFactory.create(qname="b", package="foo"), ClassFactory.create(qname="c", package="foo"), ClassFactory.create(qname="a", package="foo", module="bar"), ] random.shuffle(classes) actual = self.generator.render_package(classes) expected = "\n".join([ "from foo.bar import A as BarA", "from foo.tests import (", " A as TestsA,", " B,", " C,", ")", "", "__all__ = [", ' "BarA",', ' "TestsA",', ' "B",', ' "C",', "]", "", ]) self.assertEqual(expected, actual)
def test_render(self, mock_render_module, mock_render_package): classes = [ ClassFactory.create(package="foo.bar"), ClassFactory.create(package="bar.foo"), ClassFactory.create(package="thug.life"), ] mock_render_module.return_value = "module" mock_render_package.return_value = "package" iterator = self.generator.render(classes) cwd = Path.cwd() actual = [(out.path, out.title, out.source) for out in iterator] expected = [ (cwd.joinpath("foo/bar/__init__.py"), "init", "package"), (cwd.joinpath("foo/__init__.py"), "init", "# nothing here\n"), (cwd.joinpath("bar/foo/__init__.py"), "init", "package"), (cwd.joinpath("bar/__init__.py"), "init", "# nothing here\n"), (cwd.joinpath("thug/life/__init__.py"), "init", "package"), (cwd.joinpath("thug/__init__.py"), "init", "# nothing here\n"), (cwd.joinpath("foo/bar/tests.py"), "foo.bar.tests", "module"), (cwd.joinpath("bar/foo/tests.py"), "bar.foo.tests", "module"), (cwd.joinpath("thug/life/tests.py"), "thug.life.tests", "module"), ] self.assertEqual(expected, actual) mock_render_package.assert_has_calls([mock.call([x]) for x in classes]) mock_render_module.assert_has_calls( [mock.call(mock.ANY, [x]) for x in classes])
def test_initialize(self): classes = [ ClassFactory.create(qname="{xsdata}foo", tag=Tag.ELEMENT), ClassFactory.create(qname="{xsdata}foo", tag=Tag.COMPLEX_TYPE), ClassFactory.create(qname="{xsdata}foobar", tag=Tag.COMPLEX_TYPE), ] container = ClassContainer() container.extend(classes) expected = { "{xsdata}foo": classes[:2], "{xsdata}foobar": classes[2:], } self.assertEqual(2, len(container.data)) self.assertEqual(expected, container.data) self.assertEqual( [ "AttributeGroupHandler", "ClassExtensionHandler", "ClassEnumerationHandler", "AttributeSubstitutionHandler", "AttributeTypeHandler", "AttributeMergeHandler", "AttributeMixedContentHandler", "AttributeSanitizerHandler", ], [x.__class__.__name__ for x in container.processors], )
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_rename_classes_protects_single_element(self, mock_rename_class): classes = [ ClassFactory.create(qname="_a", tag=Tag.ELEMENT), ClassFactory.create(qname="a", tag=Tag.COMPLEX_TYPE), ] self.sanitizer.rename_classes(classes) mock_rename_class.assert_called_once_with(classes[1])
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_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_is_complex(self): obj = ClassFactory.create(tag=Tag.ELEMENT) self.assertTrue(obj.is_complex) obj = ClassFactory.create(tag=Tag.COMPLEX_TYPE) self.assertTrue(obj.is_complex) obj = ClassFactory.create(tag=Tag.SIMPLE_TYPE) self.assertFalse(obj.is_complex)
def test_copy_inner_class_skip_non_forward_reference(self): source = ClassFactory.create() target = ClassFactory.create() attr = AttrFactory.create() attr_type = AttrTypeFactory.create() ClassUtils.copy_inner_class(source, target, attr, attr_type) self.assertFalse(attr_type.circular) self.assertEqual(0, len(target.inner))
def test_process_dependency_type_with_dummy_type( self, mock_find_dependency, mock_reset_attribute_type): mock_find_dependency.return_value = ClassFactory.create( tag=Tag.ELEMENT) target = ClassFactory.create() attr = AttrFactory.create() attr_type = attr.types[0] self.processor.process_dependency_type(target, attr, attr_type) mock_reset_attribute_type.assert_called_once_with(attr_type, False)
def test_process_complex_extension_ignores_extension( self, mock_should_remove_extension, mock_should_flatten_extension): mock_should_remove_extension.return_value = False mock_should_flatten_extension.return_value = False extension = ExtensionFactory.create() target = ClassFactory.create(extensions=[extension]) source = ClassFactory.create() self.processor.process_complex_extension(source, target, extension) self.assertEqual(1, len(target.extensions))
def test_copy_inner_class_check_circular_reference(self): source = ClassFactory.create() target = ClassFactory.create() attr = AttrFactory.create() attr_type = AttrTypeFactory.create(forward=True, qname=target.qname) source.inner.append(target) ClassUtils.copy_inner_class(source, target, attr, attr_type) self.assertTrue(attr_type.circular) self.assertEqual(0, len(target.inner))
def test_copy_extensions(self): target = ClassFactory.create(extensions=ExtensionFactory.list(1)) source = ClassFactory.create(extensions=ExtensionFactory.list(2)) link_extension = ExtensionFactory.create() link_extension.restrictions.max_occurs = 2 ClassUtils.copy_extensions(source, target, link_extension) self.assertEqual(3, len(target.extensions)) self.assertEqual(2, target.extensions[1].restrictions.max_occurs) self.assertEqual(2, target.extensions[2].restrictions.max_occurs)
def test_map_binding_operation(self, mock_operation_namespace, mock_map_binding_operation_messages): definitions = Definitions(location="foo.wsdl", target_namespace="xsdata") operation = BindingOperation(name="Add") operation.ns_map["foo"] = "bar" port_operation = PortTypeOperation() config = {"a": "one", "b": "two", "style": "rpc"} name = "Calc" namespace = "SomeNS" first = ClassFactory.create(qname="some_name_first", meta_name="Envelope") second = ClassFactory.create(qname="some_name_second", meta_name="Envelope") other = ClassFactory.create() service = ClassFactory.create( qname=build_qname("xsdata", "Calc_Add"), status=Status.PROCESSED, tag=Tag.BINDING_OPERATION, module="foo", package=None, ns_map={"foo": "bar"}, attrs=[ DefinitionsMapper.build_attr("a", str(DataType.STRING), native=True, default="one"), DefinitionsMapper.build_attr("b", str(DataType.STRING), native=True, default="two"), DefinitionsMapper.build_attr("style", str(DataType.STRING), native=True, default="rpc"), DefinitionsMapper.build_attr("first", first.qname), DefinitionsMapper.build_attr("second", second.qname), ], ) mock_operation_namespace.return_value = namespace mock_map_binding_operation_messages.return_value = [ first, second, other ] result = DefinitionsMapper.map_binding_operation( definitions, operation, port_operation, config, name) expected = [first, second, other, service] self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) mock_operation_namespace.assert_called_once_with(config) mock_map_binding_operation_messages.assert_called_once_with( definitions, operation, port_operation, service.name, "rpc", namespace)
def test_process_complex_extension_copies_attributes( self, mock_compare_attributes, mock_should_flatten_extension): mock_should_flatten_extension.return_value = True extension = ExtensionFactory.create() target = ClassFactory.create() source = ClassFactory.create() self.processor.process_complex_extension(source, target, extension) mock_compare_attributes.assert_called_once_with(source, target) mock_should_flatten_extension.assert_called_once_with( source, target, extension)
def test_find_dependency(self): attr_type = AttrTypeFactory.create(qname="a") self.assertIsNone(self.processor.find_dependency(attr_type)) complex = ClassFactory.create(qname="a", tag=Tag.COMPLEX_TYPE) self.processor.container.add(complex) self.assertEqual(complex, self.processor.find_dependency(attr_type)) simple = ClassFactory.create(qname="a", tag=Tag.SIMPLE_TYPE) self.processor.container.add(simple) self.assertEqual(simple, self.processor.find_dependency(attr_type))
def test_set_circular_flag(self, mock_is_circular_dependency): source = ClassFactory.create() target = ClassFactory.create() attr = AttrFactory.create() attr_type = attr.types[0] mock_is_circular_dependency.return_value = True self.processor.set_circular_flag(source, target, attr_type) self.assertTrue(attr_type.circular) mock_is_circular_dependency.assert_called_once_with( source, target, set())
def test_process_class_group_compound_fields(self, mock_group_compound_fields): target = ClassFactory.create() inner = ClassFactory.create() target.inner.append(inner) self.container.config.output.compound_fields = True self.sanitizer.process_class(target) mock_group_compound_fields.assert_has_calls([ mock.call(inner), mock.call(target), ])
def test_rename_classes(self, mock_rename_class): classes = [ ClassFactory.create(qname="_a", tag=Tag.ELEMENT), ClassFactory.create(qname="_A", tag=Tag.ELEMENT), ClassFactory.create(qname="a", tag=Tag.COMPLEX_TYPE), ] self.sanitizer.rename_classes(classes) mock_rename_class.assert_has_calls([ mock.call(classes[0]), mock.call(classes[1]), mock.call(classes[2]), ])
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_find_inner(self, mock_process_class): obj = ClassFactory.create() first = ClassFactory.create(qname="{a}a") second = ClassFactory.create(qname="{a}b", status=Status.PROCESSED) obj.inner.extend((first, second)) def process_class(x: Class): x.status = Status.PROCESSED mock_process_class.side_effect = process_class self.assertEqual(first, self.container.find_inner(obj, "{a}a")) self.assertEqual(second, self.container.find_inner(obj, "{a}b")) mock_process_class.assert_called_once_with(first)
def test_build_envelope_fault_with_detail_messages(self): body = ClassFactory.create(qname="Body") target = ClassFactory.create() target.inner.append(body) port_type_operation = PortTypeOperation() port_type_operation.faults.append(PortTypeMessage(message="x:foo")) port_type_operation.faults.append(PortTypeMessage(message="x:bar")) definitions = Definitions() definitions.messages.append( Message(name="foo", parts=[Part(element="fooEl")])) definitions.messages.append( Message(name="bar", parts=[Part(element="barEl")])) DefinitionsMapper.build_envelope_fault(definitions, port_type_operation, target) expected_fault_attr = DefinitionsMapper.build_attr( "Fault", body.inner[0].qname, forward=True, namespace=target.namespace) str_qname = str(DataType.STRING) expected_fault_attrs = [ DefinitionsMapper.build_attr(name, str_qname, native=True, namespace="") for name in ["faultcode", "faultstring", "faultactor"] ] expected_fault_attrs.append( DefinitionsMapper.build_attr("detail", body.inner[0].inner[0].qname, forward=True, namespace="")) expected_fault_detail_attrs = [ DefinitionsMapper.build_attr(name, qname=name, namespace=target.namespace, native=False) for name in ["fooEl", "barEl"] ] self.assertEqual(1, len(body.attrs)) self.assertEqual(expected_fault_attr, body.attrs[0]) self.assertEqual(expected_fault_attrs, body.inner[0].attrs) self.assertEqual(expected_fault_detail_attrs, body.inner[0].inner[0].attrs)
def test_process(self, mock_create_substitutions, mock_process_attribute): def init_substitutions(): self.processor.substitutions = {} mock_create_substitutions.side_effect = init_substitutions target = ClassFactory.create( attrs=[AttrFactory.enumeration(), AttrFactory.any(), AttrFactory.element()] ) self.processor.process(target) self.processor.process(ClassFactory.create()) mock_process_attribute.assert_called_once_with(target, target.attrs[2]) mock_create_substitutions.assert_called_once()
def test_process_attribute_with_group(self, mock_copy_group_attributes): complex_bar = ClassFactory.create(qname="bar", tag=Tag.COMPLEX_TYPE) group_bar = ClassFactory.create(qname="bar", tag=Tag.GROUP) group_attr = AttrFactory.attribute_group(name="bar") target = ClassFactory.create() target.attrs.append(group_attr) self.processor.container.add(complex_bar) self.processor.container.add(group_bar) self.processor.container.add(target) self.processor.process_attribute(target, group_attr) mock_copy_group_attributes.assert_called_once_with( group_bar, target, group_attr)