Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List of Primitives #527

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Prev Previous commit
Next Next commit
Add XSD generation
otto-ifak committed Feb 4, 2025
commit 5363655e7710df8ceceed5f6634a4d259a3c2056
20 changes: 20 additions & 0 deletions aas_core_codegen/xsd/main.py
Original file line number Diff line number Diff line change
@@ -472,6 +472,26 @@ def _generate_xs_element_for_a_list_property(
)
else:
assert_never(our_type)
elif isinstance(type_anno.items, intermediate.PrimitiveTypeAnnotation):
xs_element_inner = ET.Element(
"xs:element",
{
"name": "v",
"type": _PRIMITIVE_MAP[type_anno.items.a_type],
"minOccurs": min_occurs,
"maxOccurs": max_occurs,
},
)
xs_sequence = ET.Element("xs:sequence")
xs_sequence.append(xs_element_inner)

xs_complex_type = ET.Element("xs:complexType")
xs_complex_type.append(xs_sequence)

xs_element = ET.Element(
"xs:element", {"name": naming.xml_property(prop.name)}
)
xs_element.append(xs_complex_type)
else:
return None, Error(
prop.parsed.node,
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="https://dummy.com" elementFormDefault="qualified" targetNamespace="https://dummy.com">
<xs:group name="listOfPrimitives">
<xs:sequence>
<xs:element name="foo" type="xs:string"/>
<xs:element name="strings">
<xs:complexType>
<xs:sequence>
<xs:element name="v" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="integers">
<xs:complexType>
<xs:sequence>
<xs:element name="v" type="xs:long" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="booleans">
<xs:complexType>
<xs:sequence>
<xs:element name="v" type="xs:boolean" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="classes">
<xs:complexType>
<xs:sequence>
<xs:element name="myClass" type="myClass_t" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:group>
<xs:group name="myClass">
<xs:sequence/>
</xs:group>
<xs:simpleType name="valueDataType">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:complexType name="listOfPrimitives_t">
<xs:sequence>
<xs:group ref="listOfPrimitives"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="myClass_t">
<xs:sequence>
<xs:group ref="myClass"/>
</xs:sequence>
</xs:complexType>
<xs:element name="list_of_primitives" type="listOfPrimitives_t"/>
</xs:schema>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Code generated to: <output dir>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="https://dummy.com"
elementFormDefault="qualified"
targetNamespace="https://dummy.com"
>
<xs:element name="list_of_primitives" type="listOfPrimitives_t" />
</xs:schema>
45 changes: 45 additions & 0 deletions test_data/xsd/test_main/list_of_primitives/meta_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from typing import List
from icontract import DBC

class Value_data_type(str, DBC):
"""
any XSD simple type as specified via :class:`Data_type_def_XSD`
"""

class Data_type_def_XSD(Enum):
"""
Enumeration listing all XSD anySimpleTypes
"""
Boolean = "xs:boolean"
Date = "xs:date"
Integer = "xs:integer"
String = "xs:string"

class My_class:
pass


class List_of_primitives:
foo: str
strings: List[str]
integers: List[int]
booleans: List[bool]
classes: List[My_class]

def __init__(
self,
foo: str,
strings: List[str],
integers: List[int],
booleans: List[bool],
classes: List[My_class],
) -> None:
self.foo = foo
self.strings = strings
self.integers = integers
self.booleans = booleans
self.classes = classes


__version__ = "dummy"
__xml_namespace__ = "https://dummy.com"
26 changes: 13 additions & 13 deletions tests/xsd/test_main.py
Original file line number Diff line number Diff line change
@@ -109,26 +109,26 @@ class Test_against_recorded(unittest.TestCase):
_REPO_DIR = pathlib.Path(os.path.realpath(__file__)).parent.parent.parent
PARENT_CASE_DIR = _REPO_DIR / "test_data" / "xsd" / "test_main"

def test_against_aas_core_meta(self) -> None:
def test_against_meta_models(self) -> None:
assert (
Test_against_recorded.PARENT_CASE_DIR.exists()
and Test_against_recorded.PARENT_CASE_DIR.is_dir()
), f"{Test_against_recorded.PARENT_CASE_DIR=}"

for module in [aas_core_meta.v3]:
case_dir = Test_against_recorded.PARENT_CASE_DIR / module.__name__
assert case_dir.is_dir(), case_dir

assert (
module.__file__ is not None
), f"Expected the module {module!r} to have a __file__, but it has None"
model_pth = pathlib.Path(module.__file__)
assert model_pth.exists() and model_pth.is_file(), model_pth
# fmt: off
test_cases = (
tests.common.find_meta_models_in_parent_directory_of_test_cases_and_modules(
parent_case_dir=Test_against_recorded.PARENT_CASE_DIR,
aas_core_meta_modules=[aas_core_meta.v3]
)
)
# fmt: on

snippets_dir = case_dir / "input/snippets"
for test_case in test_cases:
snippets_dir = test_case.case_dir / "input/snippets"
assert snippets_dir.exists() and snippets_dir.is_dir(), snippets_dir

expected_output_dir = case_dir / "expected_output"
expected_output_dir = test_case.case_dir / "expected_output"

with contextlib.ExitStack() as exit_stack:
if tests.common.RERECORD:
@@ -145,7 +145,7 @@ def test_against_aas_core_meta(self) -> None:
output_dir = pathlib.Path(tmp_dir.name)

params = aas_core_codegen.main.Parameters(
model_path=model_pth,
model_path=test_case.model_path,
target=aas_core_codegen.main.Target.XSD,
snippets_dir=snippets_dir,
output_dir=output_dir,