diff --git a/reqif/models/reqif_relation_group_type.py b/reqif/models/reqif_relation_group_type.py
index 263cdf6..2e236e5 100644
--- a/reqif/models/reqif_relation_group_type.py
+++ b/reqif/models/reqif_relation_group_type.py
@@ -1,4 +1,6 @@
-from typing import Optional
+from typing import List, Optional
+
+from reqif.models.reqif_spec_object_type import SpecAttributeDefinition
class ReqIFRelationGroupType:
@@ -9,9 +11,13 @@ def __init__( # pylint: disable=too-many-arguments
last_change: Optional[str] = None,
long_name: Optional[str] = None,
is_self_closed: bool = True,
+ attribute_definitions: Optional[List[SpecAttributeDefinition]] = None,
):
self.identifier: str = identifier
self.description: Optional[str] = description
self.last_change: Optional[str] = last_change
self.long_name: Optional[str] = long_name
self.is_self_closed: bool = is_self_closed
+ self.attribute_definitions: Optional[List[SpecAttributeDefinition]] = (
+ attribute_definitions
+ )
diff --git a/reqif/parsers/spec_types/relation_group_type_parser.py b/reqif/parsers/spec_types/relation_group_type_parser.py
index a8347eb..3b6b165 100644
--- a/reqif/parsers/spec_types/relation_group_type_parser.py
+++ b/reqif/parsers/spec_types/relation_group_type_parser.py
@@ -3,6 +3,7 @@
from reqif.helpers.lxml import lxml_is_self_closed_tag
from reqif.models.reqif_relation_group_type import ReqIFRelationGroupType
+from reqif.parsers.attribute_definition_parser import AttributeDefinitionParser
class RelationGroupTypeParser:
@@ -31,12 +32,17 @@ def parse(xml_spec_relation_type_xml) -> ReqIFRelationGroupType:
xml_attributes["LAST-CHANGE"] if "LAST-CHANGE" in xml_attributes else None
)
+ attribute_definitions = AttributeDefinitionParser.parse_attribute_definitions(
+ xml_spec_relation_type_xml
+ )
+
return ReqIFRelationGroupType(
is_self_closed=is_self_closed,
description=description,
identifier=identifier,
last_change=last_change,
long_name=long_name,
+ attribute_definitions=attribute_definitions,
)
@staticmethod
@@ -51,7 +57,16 @@ def unparse(spec_relation_type: ReqIFRelationGroupType):
output += f' LONG-NAME="{spec_relation_type.long_name}"'
if spec_relation_type.is_self_closed:
output += "/>\n"
- else:
- output += ">\n"
- output += " \n"
+ return output
+
+ output += ">\n"
+
+ if spec_relation_type.attribute_definitions is not None:
+ output += " \n"
+ output += AttributeDefinitionParser.unparse_xhtml_attribute_definition(
+ attribute_definitions=spec_relation_type.attribute_definitions
+ )
+ output += " \n"
+
+ output += " \n"
return output
diff --git a/reqif/parsers/spec_types/specification_type_parser.py b/reqif/parsers/spec_types/specification_type_parser.py
index 00eb601..de1684c 100644
--- a/reqif/parsers/spec_types/specification_type_parser.py
+++ b/reqif/parsers/spec_types/specification_type_parser.py
@@ -75,32 +75,9 @@ def unparse(spec_type: ReqIFSpecificationType) -> str:
if spec_type.spec_attributes is not None:
output += " \n"
-
- for attribute in spec_type.spec_attributes:
- output += f" <{attribute.attribute_type.get_spec_type_tag()}"
- if attribute.description is not None:
- output += f' DESC="{attribute.description}"'
- output += f' IDENTIFIER="{attribute.identifier}"'
- if attribute.editable is not None:
- editable_value = "true" if attribute.editable else "false"
- output += f' IS-EDITABLE="{editable_value}"'
- if attribute.last_change:
- output += f' LAST-CHANGE="{attribute.last_change}"'
- output += f' LONG-NAME="{attribute.long_name}"'
- output += ">\n"
- output += " \n"
- output += (
- " "
- f"<{attribute.attribute_type.get_definition_tag()}>"
- f"{attribute.datatype_definition}"
- f"{attribute.attribute_type.get_definition_tag()}>"
- "\n"
- )
- output += " \n"
- output += " "
- output += f"{attribute.attribute_type.get_spec_type_tag()}"
- output += ">\n"
-
+ output += AttributeDefinitionParser.unparse_xhtml_attribute_definition(
+ attribute_definitions=spec_type.spec_attributes
+ )
output += " \n"
output += " \n"
diff --git a/tests/integration/reqif/RELATION-GROUP-TYPE/02_spec_attributes/sample.reqif b/tests/integration/reqif/RELATION-GROUP-TYPE/02_spec_attributes/sample.reqif
new file mode 100644
index 0000000..b9ea84b
--- /dev/null
+++ b/tests/integration/reqif/RELATION-GROUP-TYPE/02_spec_attributes/sample.reqif
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ _dtype_String
+
+
+
+
+
+
+
+
diff --git a/tests/integration/reqif/RELATION-GROUP-TYPE/02_spec_attributes/test.itest b/tests/integration/reqif/RELATION-GROUP-TYPE/02_spec_attributes/test.itest
new file mode 100644
index 0000000..aa3061a
--- /dev/null
+++ b/tests/integration/reqif/RELATION-GROUP-TYPE/02_spec_attributes/test.itest
@@ -0,0 +1,3 @@
+RUN: mkdir -p %S/output
+RUN: %reqif passthrough %S/sample.reqif %S/output/sample.reqif
+RUN: %diff %S/sample.reqif %S/output/sample.reqif
diff --git a/tests/integration/reqif/SPECIFICATION-TYPE/03_spec_attribute_default_value/sample.reqif b/tests/integration/reqif/SPECIFICATION-TYPE/03_spec_attribute_default_value/sample.reqif
new file mode 100644
index 0000000..0db9cb2
--- /dev/null
+++ b/tests/integration/reqif/SPECIFICATION-TYPE/03_spec_attribute_default_value/sample.reqif
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ _dtype_String
+
+
+
+
+
+
+
+
diff --git a/tests/integration/reqif/SPECIFICATION-TYPE/03_spec_attribute_default_value/test.itest b/tests/integration/reqif/SPECIFICATION-TYPE/03_spec_attribute_default_value/test.itest
new file mode 100644
index 0000000..aa3061a
--- /dev/null
+++ b/tests/integration/reqif/SPECIFICATION-TYPE/03_spec_attribute_default_value/test.itest
@@ -0,0 +1,3 @@
+RUN: mkdir -p %S/output
+RUN: %reqif passthrough %S/sample.reqif %S/output/sample.reqif
+RUN: %diff %S/sample.reqif %S/output/sample.reqif
diff --git a/tests/unit/reqif/parsers/test_relation_group_type_parser.py b/tests/unit/reqif/parsers/test_relation_group_type_parser.py
new file mode 100644
index 0000000..2379210
--- /dev/null
+++ b/tests/unit/reqif/parsers/test_relation_group_type_parser.py
@@ -0,0 +1,39 @@
+from lxml import etree
+
+from reqif.models.reqif_relation_group_type import ReqIFRelationGroupType
+from reqif.parsers.spec_types.relation_group_type_parser import RelationGroupTypeParser
+
+
+def test_01_no_spec_attributes() -> None:
+ xml = etree.fromstring(
+ ''
+ )
+ result = RelationGroupTypeParser.parse(xml)
+ assert isinstance(result, ReqIFRelationGroupType)
+ assert result.identifier == "RGT_ID"
+ assert result.attribute_definitions is None
+
+
+def test_02_spec_attributes_round_trip() -> None:
+ xml_string = """\
+
+
+
+
+ _dtype_String
+
+
+
+"""
+ xml = etree.fromstring(xml_string)
+ result = RelationGroupTypeParser.parse(xml)
+ assert isinstance(result, ReqIFRelationGroupType)
+ assert result.attribute_definitions is not None
+ assert len(result.attribute_definitions) == 1
+ assert result.attribute_definitions[0].identifier == "_attr_comment"
+ assert result.attribute_definitions[0].long_name == "Comment"
+
+ unparsed = RelationGroupTypeParser.unparse(result)
+ assert "SPEC-ATTRIBUTES" in unparsed
+ assert "_attr_comment" in unparsed
+ assert "Comment" in unparsed
diff --git a/tests/unit/reqif/parsers/test_specification_type_parser.py b/tests/unit/reqif/parsers/test_specification_type_parser.py
index e30176f..c70e9c6 100644
--- a/tests/unit/reqif/parsers/test_specification_type_parser.py
+++ b/tests/unit/reqif/parsers/test_specification_type_parser.py
@@ -6,6 +6,30 @@
)
+def test_02_default_value_survives_unparse() -> None:
+ spec_type_string = """\
+
+
+
+
+
+
+
+ _dtype_String
+
+
+
+ """
+ xml = etree.fromstring(spec_type_string)
+ result = SpecificationTypeParser.parse(xml)
+ assert result.spec_attributes is not None
+ assert result.spec_attributes[0].default_value == "Untitled"
+
+ unparsed = SpecificationTypeParser.unparse(result)
+ assert "DEFAULT-VALUE" in unparsed
+ assert "Untitled" in unparsed
+
+
def test_01_nominal_case() -> None:
spec_type_string = """