diff --git a/docs/strictdoc_20_L1_Open_Requirements_Tool.sdoc b/docs/strictdoc_20_L1_Open_Requirements_Tool.sdoc
index 85685709d..f8d846f3d 100644
--- a/docs/strictdoc_20_L1_Open_Requirements_Tool.sdoc
+++ b/docs/strictdoc_20_L1_Open_Requirements_Tool.sdoc
@@ -6,6 +6,43 @@ ROOT: True
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATUS
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ - TITLE: RATIONALE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: COMMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[FREETEXT]
The StrictDoc project is structured around two distinct requirement documents that guide its development:
diff --git a/docs/strictdoc_21_L2_StrictDoc_Requirements.sdoc b/docs/strictdoc_21_L2_StrictDoc_Requirements.sdoc
index f27d41560..a293b1697 100644
--- a/docs/strictdoc_21_L2_StrictDoc_Requirements.sdoc
+++ b/docs/strictdoc_21_L2_StrictDoc_Requirements.sdoc
@@ -5,6 +5,43 @@ REQ_PREFIX: SDOC-SRS-
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATUS
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ - TITLE: RATIONALE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: COMMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[SECTION]
MID: bd8a7931c1e04df9bf08d291488c67aa
TITLE: SDoc data model
diff --git a/docs/strictdoc_28_Backlog.sdoc b/docs/strictdoc_28_Backlog.sdoc
index bf5ce18c8..3667ec078 100644
--- a/docs/strictdoc_28_Backlog.sdoc
+++ b/docs/strictdoc_28_Backlog.sdoc
@@ -5,6 +5,43 @@ REQ_PREFIX: SDOC-BACKLOG-
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATUS
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ - TITLE: RATIONALE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: COMMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[FREETEXT]
This document outlines the future work items for StrictDoc.
diff --git a/docs_extra/DO178_requirements.sdoc b/docs_extra/DO178_requirements.sdoc
index 5cc2fc786..bc7c9a9e3 100644
--- a/docs_extra/DO178_requirements.sdoc
+++ b/docs_extra/DO178_requirements.sdoc
@@ -10,8 +10,19 @@ OPTIONS:
[GRAMMAR]
ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
- TAG: REQUIREMENT
FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
- TITLE: UID
TYPE: String
REQUIRED: False
diff --git a/docs_extra/Zephyr_requirements.sdoc b/docs_extra/Zephyr_requirements.sdoc
index c8dbc572b..f778d7ff4 100644
--- a/docs_extra/Zephyr_requirements.sdoc
+++ b/docs_extra/Zephyr_requirements.sdoc
@@ -6,6 +6,43 @@ ROOT: True
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATUS
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ - TITLE: RATIONALE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: COMMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
MID: 68e87901205c4b0dbb6a0071479330b5
UID: ZEP-1
diff --git a/strictdoc/backend/excel/import_/excel_to_sdoc_converter.py b/strictdoc/backend/excel/import_/excel_to_sdoc_converter.py
index 97927968f..df5a11331 100644
--- a/strictdoc/backend/excel/import_/excel_to_sdoc_converter.py
+++ b/strictdoc/backend/excel/import_/excel_to_sdoc_converter.py
@@ -215,7 +215,6 @@ def create_requirement(
requirement = SDocNode(
parent=template_requirement.parent,
requirement_type=template_requirement.requirement_type,
- mid=None,
fields=list(template_requirement.enumerate_fields()),
relations=template_requirement.relations,
)
diff --git a/strictdoc/backend/reqif/p01_sdoc/reqif_to_sdoc_converter.py b/strictdoc/backend/reqif/p01_sdoc/reqif_to_sdoc_converter.py
index 4572d0a28..2a7f5eacf 100644
--- a/strictdoc/backend/reqif/p01_sdoc/reqif_to_sdoc_converter.py
+++ b/strictdoc/backend/reqif/p01_sdoc/reqif_to_sdoc_converter.py
@@ -382,7 +382,6 @@ def create_section_from_spec_object(
node: SDocNode = SDocNode(
parent=section,
requirement_type="TEXT",
- mid=None,
fields=[node_field],
relations=[],
)
@@ -499,16 +498,22 @@ def create_requirement_from_spec_object(
spec_object_type.identifier
]
)
-
+ if requirement_mid is not None:
+ fields.insert(
+ 0,
+ SDocNodeField.create_from_string(
+ None, "MID", requirement_mid, multiline=False
+ ),
+ )
requirement = SDocNode(
parent=parent_section,
requirement_type=grammar_element.tag,
- mid=requirement_mid,
fields=fields,
relations=[],
)
requirement.ng_level = level
-
+ for field_ in fields:
+ field_.parent = requirement
if foreign_key_id_or_none is not None:
spec_object_parents = reqif_bundle.get_spec_object_parents(
spec_object.identifier
diff --git a/strictdoc/backend/reqif/p01_sdoc/sdoc_to_reqif_converter.py b/strictdoc/backend/reqif/p01_sdoc/sdoc_to_reqif_converter.py
index 7fc6c5222..4c7e0d56d 100644
--- a/strictdoc/backend/reqif/p01_sdoc/sdoc_to_reqif_converter.py
+++ b/strictdoc/backend/reqif/p01_sdoc/sdoc_to_reqif_converter.py
@@ -465,6 +465,9 @@ def _convert_requirement_to_spec_object(
attributes: List[SpecObjectAttribute] = []
for field in requirement.fields_as_parsed:
+ # The MID field, if exists, is extracted separately as a ReqIF Identifier.
+ if field.field_name == "MID":
+ continue
grammar_field = grammar_element.fields_map[field.field_name]
if isinstance(grammar_field, GrammarElementFieldSingleChoice):
data_type_ref = data_types_lookup[field.field_name]
diff --git a/strictdoc/backend/sdoc/error_handling.py b/strictdoc/backend/sdoc/error_handling.py
index aa5188e4e..4fafe50dd 100644
--- a/strictdoc/backend/sdoc/error_handling.py
+++ b/strictdoc/backend/sdoc/error_handling.py
@@ -298,6 +298,25 @@ def grammar_reserved_statement_must_be_required(
filename=path_to_sdoc_file,
)
+ @staticmethod
+ def grammar_element_has_no_mid_field(
+ grammar_element: GrammarElement,
+ path_to_sdoc_file: str,
+ ):
+ return StrictDocSemanticError(
+ title=(
+ f"Grammar element '{grammar_element.tag}' is missing the MID field "
+ f"which contradicts to the DOCUMENT's ENABLE_MID setting."
+ ),
+ hint=(
+ "Either disable the ENABLE_MID option or ensure that every element has the MID field defined."
+ ),
+ example=None,
+ line=1,
+ col=1,
+ filename=path_to_sdoc_file,
+ )
+
@staticmethod
def view_references_nonexisting_grammar_element(
document: SDocDocument,
diff --git a/strictdoc/backend/sdoc/grammar/grammar.py b/strictdoc/backend/sdoc/grammar/grammar.py
index ba9fe747d..c7827eab2 100644
--- a/strictdoc/backend/sdoc/grammar/grammar.py
+++ b/strictdoc/backend/sdoc/grammar/grammar.py
@@ -175,7 +175,6 @@
SDocNode[noskipws]:
'[' !'SECTION' !SDocCompositeNodeTagName requirement_type = RequirementType ']' '\n'
- ('MID: ' mid = SingleLineString '\n')?
fields *= SDocNodeField
(
'RELATIONS:' '\n'
@@ -189,6 +188,8 @@
SDocNodeField[noskipws]:
(
+ field_name = 'MID' ': ' parts+=SingleLineString '\n'
+ |
field_name = 'UID' ': ' parts+=/{REGEX_UID}/ '\n'
|
field_name = FieldName ':'
@@ -211,8 +212,6 @@
SDocCompositeNode[noskipws]:
'[COMPOSITE_' requirement_type = RequirementType ']' '\n'
- ('MID: ' mid = SingleLineString '\n')?
-
fields *= SDocNodeField
(
'RELATIONS:' '\n'
diff --git a/strictdoc/backend/sdoc/grammar_reader.py b/strictdoc/backend/sdoc/grammar_reader.py
index 61c32bd3a..9e72d1092 100644
--- a/strictdoc/backend/sdoc/grammar_reader.py
+++ b/strictdoc/backend/sdoc/grammar_reader.py
@@ -49,7 +49,7 @@ def read(
if not grammar.has_text_element():
grammar.add_element_first(
- DocumentGrammar.create_default_text_element()
+ DocumentGrammar.create_default_text_element(grammar)
)
# HACK:
diff --git a/strictdoc/backend/sdoc/models/document_grammar.py b/strictdoc/backend/sdoc/models/document_grammar.py
index fc9e1c276..c36a30b64 100644
--- a/strictdoc/backend/sdoc/models/document_grammar.py
+++ b/strictdoc/backend/sdoc/models/document_grammar.py
@@ -201,6 +201,9 @@ def __init__(
self.is_default = False
+ self.ng_line_start: Optional[int] = None
+ self.ng_col_start: Optional[int] = None
+
@staticmethod
def create_default(parent) -> "DocumentGrammar":
text_element: GrammarElement = (
@@ -338,7 +341,7 @@ def update_with_elements(self, elements: List[GrammarElement]):
self.elements_by_type = elements_by_type
@staticmethod
- def create_default_text_element() -> GrammarElement:
+ def create_default_text_element(parent=None) -> GrammarElement:
fields: List[
Union[
GrammarElementFieldString,
@@ -360,7 +363,7 @@ def create_default_text_element() -> GrammarElement:
),
]
text_element = GrammarElement(
- parent=None, tag="TEXT", fields=fields, relations=[]
+ parent=parent, tag="TEXT", fields=fields, relations=[]
)
return text_element
diff --git a/strictdoc/backend/sdoc/models/node.py b/strictdoc/backend/sdoc/models/node.py
index 6da94d120..30c730210 100644
--- a/strictdoc/backend/sdoc/models/node.py
+++ b/strictdoc/backend/sdoc/models/node.py
@@ -102,7 +102,6 @@ def __init__(
self,
parent: Union[SDocDocument, SDocSection, "SDocCompositeNode"],
requirement_type: str,
- mid: Optional[str],
fields: List[SDocNodeField],
relations: List[Reference],
requirements: Optional[List["SDocNode"]] = None,
@@ -156,6 +155,12 @@ def __init__(
self.ng_byte_end: Optional[int] = None
self.context: SDocNodeContext = SDocNodeContext()
+ mid: Optional[str] = None
+ mid_fields: Optional[List[SDocNodeField]] = ordered_fields_lookup.get(
+ "MID", None
+ )
+ if mid_fields is not None:
+ mid = mid_fields[0].get_text_value()
self.reserved_mid: MID = MID(mid) if mid is not None else MID.create()
self.mid_permanent: bool = mid is not None
diff --git a/strictdoc/backend/sdoc/models/object_factory.py b/strictdoc/backend/sdoc/models/object_factory.py
index d0a227b23..136039cf8 100644
--- a/strictdoc/backend/sdoc/models/object_factory.py
+++ b/strictdoc/backend/sdoc/models/object_factory.py
@@ -128,7 +128,6 @@ def create_requirement(
requirement = SDocNode(
parent=parent,
requirement_type=requirement_type,
- mid=None,
fields=fields,
relations=[],
)
diff --git a/strictdoc/backend/sdoc/models/type_system.py b/strictdoc/backend/sdoc/models/type_system.py
index c8049df8b..642022fe1 100644
--- a/strictdoc/backend/sdoc/models/type_system.py
+++ b/strictdoc/backend/sdoc/models/type_system.py
@@ -6,6 +6,7 @@
class RequirementFieldName:
+ MID = "MID"
UID = "UID"
LEVEL = "LEVEL"
STATUS = "STATUS"
diff --git a/strictdoc/backend/sdoc/processor.py b/strictdoc/backend/sdoc/processor.py
index 338e908e1..2cc91c614 100644
--- a/strictdoc/backend/sdoc/processor.py
+++ b/strictdoc/backend/sdoc/processor.py
@@ -20,7 +20,6 @@
SDocNodeField,
)
from strictdoc.backend.sdoc.models.section import SDocSection
-from strictdoc.backend.sdoc.validations.sdoc_validator import SDocValidator
from strictdoc.helpers.exception import StrictDocException
from strictdoc.helpers.textx import preserve_source_location_data
@@ -73,7 +72,6 @@ def rewrite_free_text_to_text_node_if_needed(
text_node = SDocNode(
parent=parent_node,
requirement_type="TEXT",
- mid=None,
fields=fields,
relations=[],
requirements=None,
@@ -122,19 +120,16 @@ def process_document_config(self, document_config: DocumentConfig):
self.parse_context.document_config = document_config
def process_document_grammar(self, document_grammar: DocumentGrammar):
+ preserve_source_location_data(document_grammar)
if not document_grammar.has_text_element():
document_grammar.add_element_first(
- DocumentGrammar.create_default_text_element()
+ DocumentGrammar.create_default_text_element(document_grammar)
)
self.parse_context.document_grammar = document_grammar
def process_document_grammar_element(self, grammar_element: GrammarElement):
preserve_source_location_data(grammar_element)
- SDocValidator.validate_grammar_element(
- self.parse_context.path_to_sdoc_file, grammar_element
- )
-
def process_document_view(self, document_view: DocumentView):
self.parse_context.document_view = document_view
diff --git a/strictdoc/backend/sdoc/validations/sdoc_validator.py b/strictdoc/backend/sdoc/validations/sdoc_validator.py
index daf59619b..299331d9a 100644
--- a/strictdoc/backend/sdoc/validations/sdoc_validator.py
+++ b/strictdoc/backend/sdoc/validations/sdoc_validator.py
@@ -41,6 +41,7 @@ def validate_document(document: SDocDocument):
assert isinstance(document, SDocDocument), document
SDocValidator._validate_document_config(document)
SDocValidator._validate_document_view(document)
+ SDocValidator._validate_grammar(document)
@staticmethod
def validate_grammar_from_file(
@@ -51,6 +52,13 @@ def validate_grammar_from_file(
path_to_grammar, grammar_element_
)
+ @staticmethod
+ def _validate_grammar(document: SDocDocument):
+ for grammar_element_ in document.grammar.elements:
+ SDocValidator.validate_grammar_element(
+ document.meta.input_doc_full_path, grammar_element_
+ )
+
@staticmethod
def validate_grammar_element(
path_to_grammar, grammar_element: GrammarElement
@@ -62,6 +70,18 @@ def validate_grammar_element(
grammar_element.ng_line_start,
grammar_element.ng_col_start,
)
+
+ # GrammarFromFile doesn't have a parent document.
+ document: Optional[SDocDocument] = grammar_element.parent.parent
+ if document is not None and document.config.enable_mid:
+ if (
+ grammar_element.tag != "TEXT"
+ and "MID" not in grammar_element.fields_map
+ ):
+ raise StrictDocSemanticError.grammar_element_has_no_mid_field(
+ grammar_element,
+ path_to_grammar,
+ )
content_field: GrammarElementField = grammar_element.fields_map[
grammar_element.content_field[0]
]
diff --git a/strictdoc/backend/sdoc/writer.py b/strictdoc/backend/sdoc/writer.py
index 0309f5761..d5e527ca8 100644
--- a/strictdoc/backend/sdoc/writer.py
+++ b/strictdoc/backend/sdoc/writer.py
@@ -395,11 +395,6 @@ def _print_requirement_fields(
):
output = ""
- if section_content.mid_permanent or document.config.enable_mid:
- output += "MID: "
- output += section_content.reserved_mid
- output += "\n"
-
element = document.grammar.elements_by_type[
section_content.requirement_type
]
@@ -407,6 +402,10 @@ def _print_requirement_fields(
for element_field in element.fields:
field_name = element_field.title
if field_name not in section_content.ordered_fields_lookup:
+ if field_name == "MID" and document.config.enable_mid:
+ output += "MID: "
+ output += section_content.reserved_mid
+ output += "\n"
continue
fields = section_content.ordered_fields_lookup[field_name]
for field in fields:
diff --git a/strictdoc/core/traceability_index_builder.py b/strictdoc/core/traceability_index_builder.py
index 5ce6339e0..363adcfae 100644
--- a/strictdoc/core/traceability_index_builder.py
+++ b/strictdoc/core/traceability_index_builder.py
@@ -289,12 +289,6 @@ def create_from_document_tree(
document: SDocDocument
for document in document_tree.document_list:
- try:
- SDocValidator.validate_document(document)
- except StrictDocSemanticError as exc:
- print(exc.to_print_message()) # noqa: T201
- sys.exit(1)
-
"""
First, resolve all grammars that are imported from grammar files.
"""
@@ -318,6 +312,12 @@ def create_from_document_tree(
# this point.
document.grammar.parent = document
+ try:
+ SDocValidator.validate_document(document)
+ except StrictDocSemanticError as exc:
+ print(exc.to_print_message()) # noqa: T201
+ sys.exit(1)
+
if graph_database.has_link(
link_type=GraphLinkType.MID_TO_NODE,
lhs_node=document.reserved_mid,
diff --git a/strictdoc/export/html/form_objects/requirement_form_object.py b/strictdoc/export/html/form_objects/requirement_form_object.py
index cf5173642..650a624d3 100644
--- a/strictdoc/export/html/form_objects/requirement_form_object.py
+++ b/strictdoc/export/html/form_objects/requirement_form_object.py
@@ -204,7 +204,6 @@ def __init__(
requirement_mid: str,
document_mid: str,
context_document_mid: str,
- mid_field: Optional[RequirementFormField],
fields: List[RequirementFormField],
reference_fields: List[RequirementReferenceFormField],
exiting_requirement_uid: Optional[str],
@@ -220,7 +219,6 @@ def __init__(
self.requirement_mid: str = requirement_mid
self.document_mid: str = document_mid
self.context_document_mid: str = context_document_mid
- self.mid_field: Optional[RequirementFormField] = mid_field
fields_dict: dict = defaultdict(list)
for field in fields:
fields_dict[field.field_name].append(field)
@@ -306,26 +304,6 @@ def create_from_request(
)
)
- # MID field is handled separately from other fields because it not part
- # of any grammar, default or user-provided.
- mid_field: Optional[RequirementFormField] = None
- if "MID" in requirement_fields:
- requirement_field_values = requirement_fields.get("MID", [])
- for requirement_field_value in requirement_field_values:
- sanitized_field_value: str = sanitize_html_form_field(
- requirement_field_value, multiline=False
- )
- mid_field: RequirementFormField = (
- RequirementFormField.create_mid_field(
- MID(sanitized_field_value)
- )
- )
-
- # This is where the original requirement MID auto-generated
- # for a new requirement by StrictDoc can change because
- # a user has provided a new one in the input form.
- requirement_mid = sanitized_field_value
-
assert document.grammar is not None
grammar: DocumentGrammar = document.grammar
element: GrammarElement = grammar.elements_by_type[element_type]
@@ -360,7 +338,6 @@ def create_from_request(
requirement_mid=requirement_mid,
document_mid=document.reserved_mid,
context_document_mid=context_document_mid,
- mid_field=mid_field,
fields=form_fields,
reference_fields=form_ref_fields,
exiting_requirement_uid=exiting_requirement_uid,
@@ -390,14 +367,9 @@ def create_new(
grammar: DocumentGrammar = document.grammar
element: GrammarElement = grammar.elements_by_type[element_type]
- mid_field: Optional[RequirementFormField] = None
- if document.config.enable_mid:
- mid_field: RequirementFormField = (
- RequirementFormField.create_mid_field(new_requirement_mid)
- )
form_fields: List[RequirementFormField] = []
-
fields_names = list(element.fields_map.keys())
+
content_field_idx = element.get_multiline_field_index()
for field_idx, field_name in enumerate(fields_names):
@@ -417,6 +389,13 @@ def create_new(
if form_field.field_name == "UID" and next_uid is not None:
form_field.field_unescaped_value = next_uid
form_field.field_escaped_value = next_uid
+ elif form_field.field_name == "MID" and document.config.enable_mid:
+ form_field.field_unescaped_value = (
+ new_requirement_mid.get_string_value()
+ )
+ form_field.field_escaped_value = (
+ new_requirement_mid.get_string_value()
+ )
return RequirementFormObject(
is_new=True,
@@ -424,7 +403,6 @@ def create_new(
requirement_mid=new_requirement_mid,
document_mid=document.reserved_mid,
context_document_mid=context_document_mid,
- mid_field=mid_field,
fields=form_fields,
reference_fields=[],
exiting_requirement_uid=None,
@@ -447,12 +425,6 @@ def create_from_requirement(
requirement.requirement_type
]
- mid_field: Optional[RequirementFormField] = None
- if document.config.enable_mid:
- mid_field: RequirementFormField = (
- RequirementFormField.create_mid_field(requirement.reserved_mid)
- )
-
grammar_element_relations = element.get_relation_types()
form_fields: List[RequirementFormField] = []
@@ -522,7 +494,6 @@ def create_from_requirement(
requirement_mid=requirement.reserved_mid,
document_mid=document.reserved_mid,
context_document_mid=context_document_mid,
- mid_field=mid_field,
fields=form_fields,
reference_fields=form_refs_fields,
exiting_requirement_uid=requirement.reserved_uid,
@@ -641,21 +612,21 @@ def validate(
MID uniqueness check.
FIXME: MID uniqueness if a node is updated.
"""
- if self.is_new and self.mid_field is not None:
- existing_node_with_this_mid = (
- traceability_index.get_node_by_mid_weak(
- MID(self.mid_field.field_unescaped_value)
- )
- )
- if existing_node_with_this_mid is not None:
- self.add_error(
- "MID",
- (
- f"A node with this MID already exists, "
- "please select another MID: "
- f"{self.mid_field.field_unescaped_value}."
- ),
+ if self.is_new and "MID" in self.fields:
+ new_node_mid = self.fields["MID"][0].field_unescaped_value
+ if len(new_node_mid) > 0:
+ existing_node_with_this_mid = (
+ traceability_index.get_node_by_mid_weak(MID(new_node_mid))
)
+ if existing_node_with_this_mid is not None:
+ self.add_error(
+ "MID",
+ (
+ f"A node with this MID already exists, "
+ "please select another MID: "
+ f"{new_node_mid}."
+ ),
+ )
"""
UID uniqueness check.
diff --git a/strictdoc/export/html/templates/components/node_field/meta/index.jinja b/strictdoc/export/html/templates/components/node_field/meta/index.jinja
index 24dff340c..d4eae4bad 100644
--- a/strictdoc/export/html/templates/components/node_field/meta/index.jinja
+++ b/strictdoc/export/html/templates/components/node_field/meta/index.jinja
@@ -1,16 +1,4 @@
{# needs sdoc_entity, see README.txt #}
-{% if sdoc_entity.mid_permanent and sdoc_entity.reserved_mid is not none %}
- MID:
-
- {%- with field_content = sdoc_entity.reserved_mid %}
- {%- include "components/field/index.jinja" -%}
- {%- endwith -%}
-
-{% endif %}
-
{%- if sdoc_entity.has_meta -%}
{% for meta_field in sdoc_entity.enumerate_meta_fields(skip_multi_lines=True) if view_object.current_view.includes_field(sdoc_entity.requirement_type, meta_field[0]) %}
{{ meta_field[0] }}:
diff --git a/strictdoc/export/html/templates/screens/document/document/frame_requirement_form.jinja b/strictdoc/export/html/templates/screens/document/document/frame_requirement_form.jinja
index 302946357..fec5903e2 100644
--- a/strictdoc/export/html/templates/screens/document/document/frame_requirement_form.jinja
+++ b/strictdoc/export/html/templates/screens/document/document/frame_requirement_form.jinja
@@ -27,15 +27,6 @@
{% set text_field_row_context = namespace() %}
- {% if form_object.mid_field is not none %}
- {% set text_field_row_context.errors=form_object.get_errors("MID") %}
- {% set text_field_row_context.field = form_object.mid_field %}
- {% set text_field_row_context.field_editable = form_object.is_new %}
- {% set text_field_row_context.field_type = "singleline" %}
- {% set text_field_row_context.reference_mid = form_object.requirement_mid %}
- {% include "components/form/row/row_with_text_field.jinja" %}
- {% endif %}
-
{# Single-line #}
{%- for field_values_ in form_object.enumerate_fields(multiline=False) -%}
{%- for field_ in field_values_ -%}
diff --git a/strictdoc/export/spdx/spdx_to_sdoc_converter.py b/strictdoc/export/spdx/spdx_to_sdoc_converter.py
index 4c2ab2ee8..f12123a50 100644
--- a/strictdoc/export/spdx/spdx_to_sdoc_converter.py
+++ b/strictdoc/export/spdx/spdx_to_sdoc_converter.py
@@ -180,7 +180,6 @@ def _convert_document(document: SpdxDocument, sdoc_document, sdoc_parent):
requirement = SDocNode(
parent=sdoc_parent,
requirement_type="SPDX_PACKAGE",
- mid=None,
fields=[],
relations=[],
requirements=None,
@@ -211,7 +210,6 @@ def _convert_package(
requirement = SDocNode(
parent=sdoc_parent,
requirement_type="SPDX_PACKAGE",
- mid=None,
fields=[],
relations=[],
requirements=None,
@@ -252,7 +250,6 @@ def _convert_file(
requirement = SDocNode(
parent=sdoc_parent,
requirement_type="SPDX_FILE",
- mid=None,
fields=fields,
relations=[],
requirements=None,
@@ -303,7 +300,6 @@ def _convert_snippet(
requirement = SDocNode(
parent=sdoc_parent,
requirement_type="SPDX_SNIPPET",
- mid=None,
fields=fields,
relations=[],
requirements=None,
diff --git a/strictdoc/server/routers/main_router.py b/strictdoc/server/routers/main_router.py
index 734ee8801..6dc80d12b 100644
--- a/strictdoc/server/routers/main_router.py
+++ b/strictdoc/server/routers/main_router.py
@@ -1802,7 +1802,6 @@ def document__add_comment(
requirement_mid=requirement_mid,
document_mid=document.reserved_mid,
context_document_mid=context_document_mid,
- mid_field=None,
fields=[],
reference_fields=[],
exiting_requirement_uid=None,
@@ -1858,7 +1857,6 @@ def document__add_relation(
requirement_mid=requirement_mid,
document_mid=document_mid,
context_document_mid=context_document_mid,
- mid_field=None,
fields=[],
reference_fields=[],
exiting_requirement_uid=None,
diff --git a/tests/end2end/screens/document/_cross_cutting/text_nodes/update_text_node/expected_output/document.sdoc b/tests/end2end/screens/document/_cross_cutting/text_nodes/update_text_node/expected_output/document.sdoc
index 28d7d21aa..e701b1b76 100644
--- a/tests/end2end/screens/document/_cross_cutting/text_nodes/update_text_node/expected_output/document.sdoc
+++ b/tests/end2end/screens/document/_cross_cutting/text_nodes/update_text_node/expected_output/document.sdoc
@@ -5,7 +5,6 @@ TITLE: Document 1
TITLE: Section title
[TEXT]
-MID: xyz567
UID: TEXT-NODE-1
STATEMENT: >>>
Modified text statement.
diff --git a/tests/end2end/screens/document/_cross_cutting/text_nodes/update_text_node/input/document.sdoc b/tests/end2end/screens/document/_cross_cutting/text_nodes/update_text_node/input/document.sdoc
index d69a31ef8..21f8e223e 100644
--- a/tests/end2end/screens/document/_cross_cutting/text_nodes/update_text_node/input/document.sdoc
+++ b/tests/end2end/screens/document/_cross_cutting/text_nodes/update_text_node/input/document.sdoc
@@ -5,7 +5,6 @@ TITLE: Document 1
TITLE: Section title
[TEXT]
-MID: xyz567
UID: TEXT-NODE-1
STATEMENT: >>>
Text statement.
diff --git a/tests/end2end/screens/document/_cross_cutting/text_nodes/view_document_with_text_node/document.sdoc b/tests/end2end/screens/document/_cross_cutting/text_nodes/view_document_with_text_node/document.sdoc
index 4d7ca9b70..f70520fe2 100644
--- a/tests/end2end/screens/document/_cross_cutting/text_nodes/view_document_with_text_node/document.sdoc
+++ b/tests/end2end/screens/document/_cross_cutting/text_nodes/view_document_with_text_node/document.sdoc
@@ -9,14 +9,12 @@ Document free text.
TITLE: Section title
[TEXT]
-MID: xyz567
UID: TEXT-NODE-1
STATEMENT: >>>
Text statement.
<<<
[REQUIREMENT]
-MID: abcdef123456
TITLE: Requirement title
STATEMENT: >>>
Requirement statement.
diff --git a/tests/end2end/screens/document/_cross_cutting/text_nodes/view_document_with_text_node/test_case.py b/tests/end2end/screens/document/_cross_cutting/text_nodes/view_document_with_text_node/test_case.py
index 301c20cac..e912b68f7 100644
--- a/tests/end2end/screens/document/_cross_cutting/text_nodes/view_document_with_text_node/test_case.py
+++ b/tests/end2end/screens/document/_cross_cutting/text_nodes/view_document_with_text_node/test_case.py
@@ -28,4 +28,3 @@ def test(self):
screen_document.assert_not_empty_document()
screen_document.assert_text("Text statement.")
- screen_document.assert_text("abcdef123456")
diff --git a/tests/end2end/screens/document/create_requirement/_mid/_validations/create_requirement__mid__create_requirement_with_duplicate_mid/expected_output/document.sdoc b/tests/end2end/screens/document/create_requirement/_mid/_validations/create_requirement__mid__create_requirement_with_duplicate_mid/expected_output/document.sdoc
index 22907de10..891d3900d 100644
--- a/tests/end2end/screens/document/create_requirement/_mid/_validations/create_requirement__mid__create_requirement_with_duplicate_mid/expected_output/document.sdoc
+++ b/tests/end2end/screens/document/create_requirement/_mid/_validations/create_requirement__mid__create_requirement_with_duplicate_mid/expected_output/document.sdoc
@@ -4,6 +4,37 @@ TITLE: Document 1
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: True
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
MID: ec0c9dfe29554bfda007fe072120c2c4
UID: REQ-1
@@ -11,6 +42,3 @@ TITLE: Requirement title #1
STATEMENT: >>>
Requirement statement #1.
<<<
-RATIONALE: >>>
-Requirement rationale #1.
-<<<
diff --git a/tests/end2end/screens/document/create_requirement/_mid/_validations/create_requirement__mid__create_requirement_with_duplicate_mid/input/document.sdoc b/tests/end2end/screens/document/create_requirement/_mid/_validations/create_requirement__mid__create_requirement_with_duplicate_mid/input/document.sdoc
index 22907de10..891d3900d 100644
--- a/tests/end2end/screens/document/create_requirement/_mid/_validations/create_requirement__mid__create_requirement_with_duplicate_mid/input/document.sdoc
+++ b/tests/end2end/screens/document/create_requirement/_mid/_validations/create_requirement__mid__create_requirement_with_duplicate_mid/input/document.sdoc
@@ -4,6 +4,37 @@ TITLE: Document 1
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: True
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
MID: ec0c9dfe29554bfda007fe072120c2c4
UID: REQ-1
@@ -11,6 +42,3 @@ TITLE: Requirement title #1
STATEMENT: >>>
Requirement statement #1.
<<<
-RATIONALE: >>>
-Requirement rationale #1.
-<<<
diff --git a/tests/end2end/screens/document/create_requirement/_mid/_validations/create_requirement__mid__create_requirement_with_duplicate_mid/test_case.py b/tests/end2end/screens/document/create_requirement/_mid/_validations/create_requirement__mid__create_requirement_with_duplicate_mid/test_case.py
index 9e2244357..def238bdd 100644
--- a/tests/end2end/screens/document/create_requirement/_mid/_validations/create_requirement__mid__create_requirement_with_duplicate_mid/test_case.py
+++ b/tests/end2end/screens/document/create_requirement/_mid/_validations/create_requirement__mid__create_requirement_with_duplicate_mid/test_case.py
@@ -29,7 +29,7 @@ def test(self):
screen_document.assert_header_document_title("Document 1")
# Requirement 1
- requirement1_node = screen_document.get_requirement(1)
+ requirement1_node = screen_document.get_node(1)
requirement1_node_menu = requirement1_node.do_open_node_menu()
form_edit_requirement: Form_EditRequirement = (
requirement1_node_menu.do_node_add_requirement_below()
@@ -43,9 +43,6 @@ def test(self):
form_edit_requirement.do_fill_in_field_statement(
"Requirement statement #2."
)
- form_edit_requirement.do_fill_in_field_rationale(
- "Requirement rationale #2."
- )
form_edit_requirement.do_form_submit_and_catch_error(
"A node with this MID already exists, "
"please select another MID: ec0c9dfe29554bfda007fe072120c2c4."
diff --git a/tests/end2end/screens/document/create_requirement/_mid/create_requirement__mid__create_requirement_with_mid_auto_generated/input/document.sdoc b/tests/end2end/screens/document/create_requirement/_mid/create_requirement__mid__create_requirement_with_mid_auto_generated/input/document.sdoc
index a25720e14..6a3f37b29 100644
--- a/tests/end2end/screens/document/create_requirement/_mid/create_requirement__mid__create_requirement_with_mid_auto_generated/input/document.sdoc
+++ b/tests/end2end/screens/document/create_requirement/_mid/create_requirement__mid__create_requirement_with_mid_auto_generated/input/document.sdoc
@@ -2,3 +2,34 @@
TITLE: Document 1
OPTIONS:
ENABLE_MID: True
+
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: True
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
diff --git a/tests/end2end/screens/document/create_requirement/_mid/create_requirement__mid__create_requirement_with_mid_auto_generated/test_case.py b/tests/end2end/screens/document/create_requirement/_mid/create_requirement__mid__create_requirement_with_mid_auto_generated/test_case.py
index 6a88dcf41..567e6f478 100644
--- a/tests/end2end/screens/document/create_requirement/_mid/create_requirement__mid__create_requirement_with_mid_auto_generated/test_case.py
+++ b/tests/end2end/screens/document/create_requirement/_mid/create_requirement__mid__create_requirement_with_mid_auto_generated/test_case.py
@@ -39,15 +39,11 @@ def test(self):
form_edit_requirement.do_fill_in_field_statement(
"Requirement statement #1."
)
- form_edit_requirement.do_fill_in_field_rationale(
- "Requirement rationale #1."
- )
form_edit_requirement.do_form_submit()
# Expected for Requirement 1:
- requirement_1 = screen_document.get_requirement()
-
+ requirement_1 = screen_document.get_node()
requirement_1.assert_requirement_has_mid()
# FIXME
diff --git a/tests/end2end/screens/document/create_requirement/_mid/update_requirement__mid__update_requirement_preserves_mid/expected_output/document.sdoc b/tests/end2end/screens/document/create_requirement/_mid/update_requirement__mid__update_requirement_preserves_mid/expected_output/document.sdoc
new file mode 100644
index 000000000..4465f88fa
--- /dev/null
+++ b/tests/end2end/screens/document/create_requirement/_mid/update_requirement__mid__update_requirement_preserves_mid/expected_output/document.sdoc
@@ -0,0 +1,43 @@
+[DOCUMENT]
+MID: 6c85e9531ebd4764a52c6fb339cad78a
+TITLE: Document 1
+OPTIONS:
+ ENABLE_MID: True
+
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: True
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
+[REQUIREMENT]
+MID: ABCD1234
+TITLE: Requirement title #1
+STATEMENT: >>>
+MODIFIED requirement statement #1.
+<<<
diff --git a/tests/end2end/screens/document/create_requirement/_mid/update_requirement__mid__update_requirement_preserves_mid/input/document.sdoc b/tests/end2end/screens/document/create_requirement/_mid/update_requirement__mid__update_requirement_preserves_mid/input/document.sdoc
new file mode 100644
index 000000000..d29ea9a09
--- /dev/null
+++ b/tests/end2end/screens/document/create_requirement/_mid/update_requirement__mid__update_requirement_preserves_mid/input/document.sdoc
@@ -0,0 +1,40 @@
+[DOCUMENT]
+MID: 6c85e9531ebd4764a52c6fb339cad78a
+TITLE: Document 1
+OPTIONS:
+ ENABLE_MID: True
+
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: True
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
+[REQUIREMENT]
+MID: ABCD1234
+STATEMENT: System A shall do B.
diff --git a/tests/end2end/screens/document/create_requirement/_mid/update_requirement__mid__update_requirement_preserves_mid/test_case.py b/tests/end2end/screens/document/create_requirement/_mid/update_requirement__mid__update_requirement_preserves_mid/test_case.py
new file mode 100644
index 000000000..c8dffd2f3
--- /dev/null
+++ b/tests/end2end/screens/document/create_requirement/_mid/update_requirement__mid__update_requirement_preserves_mid/test_case.py
@@ -0,0 +1,47 @@
+from tests.end2end.e2e_case import E2ECase
+from tests.end2end.end2end_test_setup import End2EndTestSetup
+from tests.end2end.helpers.screens.document.form_edit_requirement import (
+ Form_EditRequirement,
+)
+from tests.end2end.helpers.screens.project_index.screen_project_index import (
+ Screen_ProjectIndex,
+)
+from tests.end2end.server import SDocTestServer
+
+
+class Test(E2ECase):
+ def test(self):
+ test_setup = End2EndTestSetup(path_to_test_file=__file__)
+
+ with SDocTestServer(
+ input_path=test_setup.path_to_sandbox
+ ) as test_server:
+ self.open(test_server.get_host_and_port())
+
+ screen_project_index = Screen_ProjectIndex(self)
+
+ screen_project_index.assert_on_screen()
+ screen_project_index.assert_contains_document("Document 1")
+
+ screen_document = screen_project_index.do_click_on_first_document()
+
+ screen_document.assert_on_screen_document()
+ screen_document.assert_header_document_title("Document 1")
+
+ # Requirement 1
+ requirement_node = screen_document.get_node()
+ form_edit_requirement: Form_EditRequirement = (
+ requirement_node.do_open_form_edit_requirement()
+ )
+
+ form_edit_requirement.do_fill_in_field_title("Requirement title #1")
+ form_edit_requirement.do_fill_in_field_statement(
+ "MODIFIED requirement statement #1."
+ )
+ form_edit_requirement.do_form_submit()
+
+ # Expected for Requirement 1:
+ requirement_1 = screen_document.get_node()
+ requirement_1.assert_requirement_has_mid()
+
+ assert test_setup.compare_sandbox_and_expected_output()
diff --git a/tests/end2end/screens/document/view_document/_grammar_from_file/view_document_with_grammar_from_file/grammar.sgra b/tests/end2end/screens/document/view_document/_grammar_from_file/view_document_with_grammar_from_file/grammar.sgra
index d8ba85cf9..9e68cdd6e 100644
--- a/tests/end2end/screens/document/view_document/_grammar_from_file/view_document_with_grammar_from_file/grammar.sgra
+++ b/tests/end2end/screens/document/view_document/_grammar_from_file/view_document_with_grammar_from_file/grammar.sgra
@@ -2,6 +2,9 @@
ELEMENTS:
- TAG: REQUIREMENT
FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: True
- TITLE: TITLE
TYPE: String
REQUIRED: True
diff --git a/tests/end2end/screens/document/view_document/view_document_with_one_requirement/document.sdoc b/tests/end2end/screens/document/view_document/view_document_with_one_requirement/document.sdoc
index a27354dbd..6e584a734 100644
--- a/tests/end2end/screens/document/view_document/view_document_with_one_requirement/document.sdoc
+++ b/tests/end2end/screens/document/view_document/view_document_with_one_requirement/document.sdoc
@@ -1,6 +1,20 @@
[DOCUMENT]
TITLE: Document 1
+[GRAMMAR]
+ELEMENTS:
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: True
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: True
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: True
+
[REQUIREMENT]
MID: abcdef123456
TITLE: Requirement title
diff --git a/tests/integration/backend/reqif/profiles/p01_sdoc/end_to_end/--reqif-enable-mid/01_cli_option/sample.sdoc b/tests/integration/backend/reqif/profiles/p01_sdoc/end_to_end/--reqif-enable-mid/01_cli_option/sample.sdoc
index 53a7a4013..cc1a3c2bc 100644
--- a/tests/integration/backend/reqif/profiles/p01_sdoc/end_to_end/--reqif-enable-mid/01_cli_option/sample.sdoc
+++ b/tests/integration/backend/reqif/profiles/p01_sdoc/end_to_end/--reqif-enable-mid/01_cli_option/sample.sdoc
@@ -8,6 +8,9 @@ OPTIONS:
ELEMENTS:
- TAG: REQUIREMENT
FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
- TITLE: UID
TYPE: String
REQUIRED: False
diff --git a/tests/integration/backend/reqif/profiles/p01_sdoc/end_to_end/--reqif-enable-mid/02_toml_option/sample.sdoc b/tests/integration/backend/reqif/profiles/p01_sdoc/end_to_end/--reqif-enable-mid/02_toml_option/sample.sdoc
index 53a7a4013..cc1a3c2bc 100644
--- a/tests/integration/backend/reqif/profiles/p01_sdoc/end_to_end/--reqif-enable-mid/02_toml_option/sample.sdoc
+++ b/tests/integration/backend/reqif/profiles/p01_sdoc/end_to_end/--reqif-enable-mid/02_toml_option/sample.sdoc
@@ -8,6 +8,9 @@ OPTIONS:
ELEMENTS:
- TAG: REQUIREMENT
FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
- TITLE: UID
TYPE: String
REQUIRED: False
diff --git a/tests/integration/commands/bypass/40_generate_mid/input.sdoc b/tests/integration/commands/bypass/40_generate_mid/input.sdoc
index b47c1e57c..36a4c6597 100644
--- a/tests/integration/commands/bypass/40_generate_mid/input.sdoc
+++ b/tests/integration/commands/bypass/40_generate_mid/input.sdoc
@@ -3,6 +3,23 @@ TITLE: Hello world doc
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+
[SECTION]
TITLE: Section 1
diff --git a/tests/integration/commands/export/json/01_basic_json_export/input1.sdoc b/tests/integration/commands/export/json/01_basic_json_export/input1.sdoc
index 4b6cde3f2..14c489df2 100644
--- a/tests/integration/commands/export/json/01_basic_json_export/input1.sdoc
+++ b/tests/integration/commands/export/json/01_basic_json_export/input1.sdoc
@@ -4,6 +4,26 @@ TITLE: Dummy Software Requirements Specification #1
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
MID: c165cc52af20417e9199e30a4e17f138
UID: REQ-1
diff --git a/tests/integration/commands/export/json/01_basic_json_export/input2.sdoc b/tests/integration/commands/export/json/01_basic_json_export/input2.sdoc
index e4df7f7e3..e1ed1209b 100644
--- a/tests/integration/commands/export/json/01_basic_json_export/input2.sdoc
+++ b/tests/integration/commands/export/json/01_basic_json_export/input2.sdoc
@@ -4,6 +4,26 @@ TITLE: Dummy Software Requirements Specification #2
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
MID: 95e3198bbbdf44d691daa869efc79323
UID: LREQ-1
diff --git a/tests/integration/commands/export/spdx/01_minimal_document_mid_enabled/input1.sdoc b/tests/integration/commands/export/spdx/01_minimal_document_mid_enabled/input1.sdoc
index 4b6cde3f2..14c489df2 100644
--- a/tests/integration/commands/export/spdx/01_minimal_document_mid_enabled/input1.sdoc
+++ b/tests/integration/commands/export/spdx/01_minimal_document_mid_enabled/input1.sdoc
@@ -4,6 +4,26 @@ TITLE: Dummy Software Requirements Specification #1
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
MID: c165cc52af20417e9199e30a4e17f138
UID: REQ-1
diff --git a/tests/integration/commands/export/spdx/01_minimal_document_mid_enabled/input2.sdoc b/tests/integration/commands/export/spdx/01_minimal_document_mid_enabled/input2.sdoc
index e4df7f7e3..e1ed1209b 100644
--- a/tests/integration/commands/export/spdx/01_minimal_document_mid_enabled/input2.sdoc
+++ b/tests/integration/commands/export/spdx/01_minimal_document_mid_enabled/input2.sdoc
@@ -4,6 +4,26 @@ TITLE: Dummy Software Requirements Specification #2
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
MID: 95e3198bbbdf44d691daa869efc79323
UID: LREQ-1
diff --git a/tests/integration/commands/manage/auto-uid/_cross_cutting/01_issue_1630_autouid_must_preserve_relations/input.sdoc b/tests/integration/commands/manage/auto-uid/_cross_cutting/01_issue_1630_autouid_must_preserve_relations/input.sdoc
index 9acddc80c..6abcde453 100644
--- a/tests/integration/commands/manage/auto-uid/_cross_cutting/01_issue_1630_autouid_must_preserve_relations/input.sdoc
+++ b/tests/integration/commands/manage/auto-uid/_cross_cutting/01_issue_1630_autouid_must_preserve_relations/input.sdoc
@@ -14,6 +14,9 @@ OPTIONS:
ELEMENTS:
- TAG: REQUIREMENT
FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
- TITLE: UID
TYPE: String
REQUIRED: False
diff --git a/tests/integration/features/diff/_mid_match/01__mid_match__requirements__from_requirement_to_requirement_no_uid/lhs/input.sdoc b/tests/integration/features/diff/_mid_match/01__mid_match__requirements__from_requirement_to_requirement_no_uid/lhs/input.sdoc
index 9bdc0674f..9c0ef896c 100644
--- a/tests/integration/features/diff/_mid_match/01__mid_match__requirements__from_requirement_to_requirement_no_uid/lhs/input.sdoc
+++ b/tests/integration/features/diff/_mid_match/01__mid_match__requirements__from_requirement_to_requirement_no_uid/lhs/input.sdoc
@@ -1,6 +1,26 @@
[DOCUMENT]
TITLE: Hello world doc
+[GRAMMAR]
+ELEMENTS:
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
MID: ABCD0123
TITLE: Requirement #1
diff --git a/tests/integration/features/diff/_mid_match/01__mid_match__requirements__from_requirement_to_requirement_no_uid/rhs/input.sdoc b/tests/integration/features/diff/_mid_match/01__mid_match__requirements__from_requirement_to_requirement_no_uid/rhs/input.sdoc
index d65cd32da..bfb521777 100644
--- a/tests/integration/features/diff/_mid_match/01__mid_match__requirements__from_requirement_to_requirement_no_uid/rhs/input.sdoc
+++ b/tests/integration/features/diff/_mid_match/01__mid_match__requirements__from_requirement_to_requirement_no_uid/rhs/input.sdoc
@@ -1,6 +1,26 @@
[DOCUMENT]
TITLE: Hello world doc
+[GRAMMAR]
+ELEMENTS:
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
MID: ABCD0123
TITLE: Modified title
diff --git a/tests/integration/features/document_grammar/validation/07_grammar_missing_reserved_statement_field/test.itest b/tests/integration/features/document_grammar/validation/07_grammar_missing_reserved_statement_field/test.itest
index 0519fbd8b..f6b569487 100644
--- a/tests/integration/features/document_grammar/validation/07_grammar_missing_reserved_statement_field/test.itest
+++ b/tests/integration/features/document_grammar/validation/07_grammar_missing_reserved_statement_field/test.itest
@@ -1,6 +1,6 @@
RUN: %expect_exit 1 %strictdoc export %S --output-dir Output/ | filecheck %s --dump-input=fail
+CHECK: error: could not parse file: {{.*}}input.sdoc.
CHECK: Semantic error: Grammar element 'REQUIREMENT' is missing a reserved content field declaration, one of {STATEMENT, DESCRIPTION, CONTENT}.
CHECK: Location: {{.*}}input.sdoc:6:1
CHECK: Hint: A content field plays a key role in StrictDoc's HTML user interface as well as in the other export formats. It is a reserved field that any grammar element must have.
-CHECK: error: Parallelizer: One of the child processes has exited prematurely.
diff --git a/tests/integration/features/document_grammar/validation/08_grammar_reserved_statement_field_must_be_declared_REQUIRED_True/test.itest b/tests/integration/features/document_grammar/validation/08_grammar_reserved_statement_field_must_be_declared_REQUIRED_True/test.itest
index f37adbe8b..0564725ac 100644
--- a/tests/integration/features/document_grammar/validation/08_grammar_reserved_statement_field_must_be_declared_REQUIRED_True/test.itest
+++ b/tests/integration/features/document_grammar/validation/08_grammar_reserved_statement_field_must_be_declared_REQUIRED_True/test.itest
@@ -1,6 +1,6 @@
RUN: %expect_exit 1 %strictdoc export %S --output-dir Output/ | filecheck %s --dump-input=fail
+CHECK: error: could not parse file: {{.*}}input.sdoc.
CHECK: Semantic error: Grammar element 'REQUIREMENT's DESCRIPTION field must be declared as 'REQUIRED: True'.
CHECK: Location: {{.*}}input.sdoc:6:1
CHECK: Hint: A content field plays a key role in StrictDoc's HTML user interface as well as in the other export formats. It is a reserved field that any grammar element must have with 'REQUIRED: True'.
-CHECK: error: Parallelizer: One of the child processes has exited prematurely.
diff --git a/tests/integration/features/document_grammar/validation/09_ENABLE_MID_enabled_but_missing_MID_field/input.sdoc b/tests/integration/features/document_grammar/validation/09_ENABLE_MID_enabled_but_missing_MID_field/input.sdoc
new file mode 100644
index 000000000..b47c1e57c
--- /dev/null
+++ b/tests/integration/features/document_grammar/validation/09_ENABLE_MID_enabled_but_missing_MID_field/input.sdoc
@@ -0,0 +1,15 @@
+[DOCUMENT]
+TITLE: Hello world doc
+OPTIONS:
+ ENABLE_MID: True
+
+[SECTION]
+TITLE: Section 1
+
+[REQUIREMENT]
+TITLE: Req-1
+
+[REQUIREMENT]
+TITLE: Req-2
+
+[/SECTION]
diff --git a/tests/integration/features/document_grammar/validation/09_ENABLE_MID_enabled_but_missing_MID_field/test.itest b/tests/integration/features/document_grammar/validation/09_ENABLE_MID_enabled_but_missing_MID_field/test.itest
new file mode 100644
index 000000000..cfbe87957
--- /dev/null
+++ b/tests/integration/features/document_grammar/validation/09_ENABLE_MID_enabled_but_missing_MID_field/test.itest
@@ -0,0 +1,6 @@
+RUN: %expect_exit 1 %strictdoc export %S --output-dir Output/ | filecheck %s --dump-input=fail
+
+CHECK: error: could not parse file: {{.*}}input.sdoc.
+CHECK: Semantic error: Grammar element 'REQUIREMENT' is missing the MID field which contradicts to the DOCUMENT's ENABLE_MID setting.
+CHECK: Location: {{.*}}input.sdoc:1:1
+CHECK: Hint: Either disable the ENABLE_MID option or ensure that every element has the MID field defined.
diff --git a/tests/integration/features/html2pdf/02_three_top_level_requirements/input.sdoc b/tests/integration/features/html2pdf/02_three_top_level_requirements/input.sdoc
index 666c2de94..0e43e1c54 100644
--- a/tests/integration/features/html2pdf/02_three_top_level_requirements/input.sdoc
+++ b/tests/integration/features/html2pdf/02_three_top_level_requirements/input.sdoc
@@ -4,6 +4,37 @@ TITLE: Dummy Software Requirements Specification #1
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: True
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
MID: c165cc52af20417e9199e30a4e17f138
UID: REQ-1
diff --git a/tests/integration/features/html2pdf/02_three_top_level_requirements/nested/input2.sdoc b/tests/integration/features/html2pdf/02_three_top_level_requirements/nested/input2.sdoc
index cfb0e235f..888807daf 100644
--- a/tests/integration/features/html2pdf/02_three_top_level_requirements/nested/input2.sdoc
+++ b/tests/integration/features/html2pdf/02_three_top_level_requirements/nested/input2.sdoc
@@ -1,6 +1,37 @@
[DOCUMENT]
TITLE: Dummy Software Requirements Specification #2
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: True
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
TITLE: Dummy high-level requirement #1
STATEMENT: System ABC shall do 1.
diff --git a/tests/integration/features/html2pdf/02_three_top_level_requirements/nested/subnested/input3.sdoc b/tests/integration/features/html2pdf/02_three_top_level_requirements/nested/subnested/input3.sdoc
index 22f17211f..7cb60db9f 100644
--- a/tests/integration/features/html2pdf/02_three_top_level_requirements/nested/subnested/input3.sdoc
+++ b/tests/integration/features/html2pdf/02_three_top_level_requirements/nested/subnested/input3.sdoc
@@ -3,6 +3,37 @@ TITLE: Dummy Software Requirements Specification #3
OPTIONS:
ENABLE_MID: True
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: True
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
TITLE: Dummy high-level requirement #1
STATEMENT: System ABC shall do 1.
diff --git a/tests/integration/features/machine_identifiers_MID/_validations/03_requirement_mid_must_be_unique/input.sdoc b/tests/integration/features/machine_identifiers_MID/_validations/03_requirement_mid_must_be_unique/input.sdoc
index 2b8cebb7a..eba04cb87 100644
--- a/tests/integration/features/machine_identifiers_MID/_validations/03_requirement_mid_must_be_unique/input.sdoc
+++ b/tests/integration/features/machine_identifiers_MID/_validations/03_requirement_mid_must_be_unique/input.sdoc
@@ -1,6 +1,26 @@
[DOCUMENT]
TITLE: Doc 1
+[GRAMMAR]
+ELEMENTS:
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
MID: ABC0123
TITLE: Foo
diff --git a/tests/integration/features/machine_identifiers_MID/_validations/03_requirement_mid_must_be_unique/input2.sdoc b/tests/integration/features/machine_identifiers_MID/_validations/03_requirement_mid_must_be_unique/input2.sdoc
index 62d3807ee..db138aa08 100644
--- a/tests/integration/features/machine_identifiers_MID/_validations/03_requirement_mid_must_be_unique/input2.sdoc
+++ b/tests/integration/features/machine_identifiers_MID/_validations/03_requirement_mid_must_be_unique/input2.sdoc
@@ -1,6 +1,26 @@
[DOCUMENT]
TITLE: Doc 2
+[GRAMMAR]
+ELEMENTS:
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: TITLE
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+ RELATIONS:
+ - TYPE: Parent
+ - TYPE: File
+
[REQUIREMENT]
MID: ABC0123
TITLE: Foo
diff --git a/tests/integration/scripting_examples/reqif/02_user_provided_example/script.py b/tests/integration/scripting_examples/reqif/02_user_provided_example/script.py
index dee562d07..3069b0ba3 100644
--- a/tests/integration/scripting_examples/reqif/02_user_provided_example/script.py
+++ b/tests/integration/scripting_examples/reqif/02_user_provided_example/script.py
@@ -485,7 +485,7 @@ def create_requirement_from_spec_object(
)
)
requirement = SDocNode(
- parent=parent_section, requirement_type="REQUIREMENT", mid=None, fields=fields, relations=[]
+ parent=parent_section, requirement_type="REQUIREMENT", fields=fields, relations=[]
)
if foreign_key_id_or_none is not None:
diff --git a/tests/unit/strictdoc/backend/sdoc/test_dsl_passthrough.py b/tests/unit/strictdoc/backend/sdoc/test_dsl_passthrough.py
index 535057843..95c048f68 100644
--- a/tests/unit/strictdoc/backend/sdoc/test_dsl_passthrough.py
+++ b/tests/unit/strictdoc/backend/sdoc/test_dsl_passthrough.py
@@ -149,6 +149,25 @@ def test_020_requirement_mid():
[DOCUMENT]
TITLE: Test Doc
+[GRAMMAR]
+ELEMENTS:
+- TAG: TEXT
+ FIELDS:
+ - TITLE: UID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: True
+- TAG: REQUIREMENT
+ FIELDS:
+ - TITLE: MID
+ TYPE: String
+ REQUIRED: False
+ - TITLE: STATEMENT
+ TYPE: String
+ REQUIRED: False
+
[REQUIREMENT]
MID: abcdef123456
STATEMENT: >>>
@@ -165,7 +184,6 @@ def test_020_requirement_mid():
writer = SDWriter()
output = writer.write(document)
-
assert input_sdoc == output