Skip to content

Commit a43e47f

Browse files
authored
Merge pull request #2220 from strictdoc-project/stanislaw/merge_nodes
Migration: SDoc model: Merge Section, Node, Composite Node into just Node
2 parents 5aa3238 + 66f4e65 commit a43e47f

File tree

114 files changed

+766
-583
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+766
-583
lines changed

docs/strictdoc_02_feature_map.sdoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ ELEMENTS:
3535
REQUIRED: False
3636
- TITLE: STATEMENT
3737
TYPE: String
38-
REQUIRED: False
38+
REQUIRED: True
3939
- TITLE: RATIONALE
4040
TYPE: String
4141
REQUIRED: False

docs/strictdoc_05_troubleshooting.sdoc

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,23 @@ VERSION: Git commit: @GIT_VERSION, Git branch: @GIT_BRANCH
66
DATE: @GIT_COMMIT_DATETIME
77
OPTIONS:
88
ENABLE_MID: True
9+
REQUIREMENT_STYLE: Narrative
910

1011
[GRAMMAR]
1112
ELEMENTS:
13+
- TAG: SECTION
14+
PROPERTIES:
15+
IS_COMPOSITE: True
16+
FIELDS:
17+
- TITLE: MID
18+
TYPE: String
19+
REQUIRED: False
20+
- TITLE: UID
21+
TYPE: String
22+
REQUIRED: False
23+
- TITLE: TITLE
24+
TYPE: String
25+
REQUIRED: True
1226
- TAG: TEXT
1327
FIELDS:
1428
- TITLE: MID
@@ -27,7 +41,7 @@ STATEMENT: >>>
2741
This document summarizes solutions to the most common issues reported by StrictDoc users.
2842
<<<
2943

30-
[SECTION]
44+
[[SECTION]]
3145
MID: 17152ac7de9f4c138b85e2956091206f
3246
TITLE: Caching issues
3347

@@ -43,4 +57,4 @@ StrictDoc caches many artifacts on disk. Some artifacts are cached using Python
4357
The pickle module serializes Python objects to disk. The issue with this approach is that when StrictDoc changes the schema of its objects (e.g., when SDocNode or SDocDocument objects gain a new property or a property type changes), an outdated object may be read from the cache after upgrading to a new StrictDoc version. While a more systematic solution might be implemented in the future, the current workaround is to manually delete the StrictDoc cache folder.
4458
<<<
4559

46-
[/SECTION]
60+
[[/SECTION]]

strictdoc/backend/excel/import_/excel_to_sdoc_converter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ def create_document(
152152
parent=None,
153153
tag="REQUIREMENT",
154154
property_is_composite="",
155+
property_view_style="",
155156
fields=fields,
156157
relations=[],
157158
)

strictdoc/backend/reqif/p01_sdoc/reqif_to_sdoc_converter.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ def _create_document_from_reqif_specification(
134134
if not isinstance(spec_object_type_, ReqIFSpecObjectType):
135135
continue
136136

137+
# FIXME: [[NODE]]
138+
if spec_object_type_.long_name == "SECTION":
139+
continue
140+
137141
grammar_element: GrammarElement = P01_ReqIFToSDocConverter.create_grammar_element_from_spec_object_type(
138142
spec_object_type=spec_object_type_,
139143
reqif_bundle=reqif_bundle,
@@ -315,6 +319,7 @@ def create_grammar_element_from_spec_object_type(
315319
# FIXME: MERGE NODES
316320
# When the migration is done, make the nodes to be always recursive.
317321
property_is_composite="",
322+
property_view_style="",
318323
fields=fields,
319324
relations=[],
320325
)

strictdoc/backend/sdoc/error_handling.py

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,11 @@ def missing_required_field(
145145
grammar_fields = document_grammar.dump_fields(node.node_type)
146146
return StrictDocSemanticError(
147147
title=(
148-
f"Requirement is missing a field that is required by "
148+
f"Node is missing a field that is required by "
149149
f"grammar: {grammar_field.title}."
150150
),
151151
hint=(
152-
f"Requirement fields: [{node.dump_fields_as_parsed()}], "
152+
f"Node fields: [{node.dump_fields_as_parsed()}], "
153153
f"grammar fields: [{grammar_fields}]."
154154
),
155155
example=None,
@@ -339,53 +339,6 @@ def invalid_marker_role(
339339
filename=path_to_src_file,
340340
)
341341

342-
@staticmethod
343-
def grammar_missing_reserved_statement(
344-
grammar_element: GrammarElement,
345-
path_to_sdoc_file: str,
346-
line: int,
347-
column: int,
348-
) -> "StrictDocSemanticError":
349-
return StrictDocSemanticError(
350-
title=(
351-
f"Grammar element '{grammar_element.tag}' is missing a reserved"
352-
" content field declaration, one of {STATEMENT, DESCRIPTION, CONTENT}."
353-
),
354-
hint=(
355-
"A content field plays a key role in StrictDoc's HTML user interface "
356-
"as well as in the other export formats. It is a reserved field"
357-
" that any grammar element must have."
358-
),
359-
example=None,
360-
line=line,
361-
col=column,
362-
filename=path_to_sdoc_file,
363-
)
364-
365-
@staticmethod
366-
def grammar_reserved_statement_must_be_required(
367-
grammar_element: GrammarElement,
368-
field_title: str,
369-
path_to_sdoc_file: str,
370-
line: int,
371-
column: int,
372-
) -> "StrictDocSemanticError":
373-
return StrictDocSemanticError(
374-
title=(
375-
f"Grammar element '{grammar_element.tag}'s {field_title} field "
376-
f"must be declared as 'REQUIRED: True'."
377-
),
378-
hint=(
379-
"A content field plays a key role in StrictDoc's HTML user interface "
380-
"as well as in the other export formats. It is a reserved field"
381-
" that any grammar element must have with 'REQUIRED: True'."
382-
),
383-
example=None,
384-
line=line,
385-
col=column,
386-
filename=path_to_sdoc_file,
387-
)
388-
389342
@staticmethod
390343
def grammar_element_has_no_mid_field(
391344
grammar_element: GrammarElement,

strictdoc/backend/sdoc/grammar/grammar.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@
120120
;
121121
122122
RequirementStyleChoice[noskipws]:
123-
'Inline' | 'Simple' | 'Narrative' | 'Table' | 'Zebra'
123+
'Plain' | 'Inline' | 'Simple' | 'Narrative' | 'Table' | 'Zebra'
124124
;
125125
126126
RequirementHasTitleChoice[noskipws]:
@@ -181,7 +181,7 @@
181181
182182
SDocNode[noskipws]:
183183
'[' !'SECTION' !SDocCompositeNodeTagName node_type = RequirementType ']' '\n'
184-
fields *= SDocNodeField
184+
fields += SDocNodeField
185185
(
186186
'RELATIONS:' '\n'
187187
(relations += Reference)
@@ -191,7 +191,7 @@
191191
SDocCompositeNodeNew[noskipws]:
192192
'[[' node_type = RequirementType ']]' '\n'
193193
194-
fields *= SDocNodeField
194+
fields += SDocNodeField
195195
(
196196
'RELATIONS:' '\n'
197197
(relations += Reference)

strictdoc/backend/sdoc/grammar/grammar_grammar.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
'- TAG: ' tag = RequirementType '\n'
1818
(
1919
' PROPERTIES:' '\n'
20-
' IS_COMPOSITE: ' property_is_composite=/(True|False)/ '\n'
20+
(' IS_COMPOSITE: ' property_is_composite=/(True|False)/ '\n' )?
21+
(' VIEW_STYLE: ' property_view_style=/(Plain|Simple|Inline|Narrative|Table|Zebra)/ '\n')?
2122
)?
2223
' FIELDS:' '\n'
2324
fields += GrammarElementField

strictdoc/backend/sdoc/models/document_config.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,18 @@ def get_markup(self) -> str:
119119
return self.markup
120120

121121
def get_requirement_style_mode(self) -> str:
122-
if self.requirement_style is None or self.requirement_style in (
122+
if (
123+
self.requirement_style is None
124+
or self.requirement_style == "Narrative"
125+
):
126+
return "narrative"
127+
if self.requirement_style == "Plain":
128+
return "plain"
129+
if self.requirement_style in (
123130
"Inline",
124131
"Simple",
125132
):
126133
return "simple"
127-
if self.requirement_style == "Narrative":
128-
return "narrative"
129134
if self.requirement_style == "Table":
130135
return "table"
131136
if self.requirement_style == "Zebra":

strictdoc/backend/sdoc/models/document_grammar.py

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def __init__(
2525
parent: Optional["DocumentGrammar"],
2626
tag: str,
2727
property_is_composite: str,
28+
property_view_style: str,
2829
fields: List[
2930
Union[
3031
GrammarElementFieldString,
@@ -43,6 +44,20 @@ def __init__(
4344
if property_is_composite == ""
4445
else (property_is_composite == "True")
4546
)
47+
48+
assert property_view_style in (
49+
"",
50+
"Plain",
51+
"Narrative",
52+
"Simple",
53+
"Inline",
54+
"Table",
55+
"Zebra",
56+
)
57+
self.property_view_style: Optional[str] = (
58+
property_view_style.lower() if property_view_style != "" else None
59+
)
60+
4661
self.fields: List[
4762
Union[
4863
GrammarElementFieldString,
@@ -76,9 +91,31 @@ def __init__(
7691
else:
7792
pass
7893
self.fields_map: Dict[str, GrammarElementField] = fields_map
94+
95+
self.field_titles: List[str] = list(
96+
map(lambda field__: field__.title, self.fields)
97+
)
98+
7999
self.content_field: Tuple[str, int] = (
80100
statement_field or description_field or content_field or ("", -1)
81101
)
102+
103+
# Some nodes have the content field, e.g., STATEMENT or DESCRIPTION,
104+
# some don't. For those that don't, use TITLE as a boundary between
105+
# the single-line and multiline.
106+
multiline_field_index = self.content_field[1]
107+
if multiline_field_index == -1:
108+
try:
109+
multiline_field_index = self.get_field_titles().index("TITLE")
110+
except ValueError as value_error_:
111+
raise RuntimeError(
112+
(
113+
f"The grammar element {self.tag} must have at least one of the "
114+
f"following fields: TITLE, STATEMENT, DESCRIPTION, CONTENT."
115+
),
116+
) from value_error_
117+
self.multiline_field_index: int = multiline_field_index
118+
82119
self.mid: MID = MID.create()
83120
self.ng_line_start: Optional[int] = None
84121
self.ng_col_start: Optional[int] = None
@@ -89,6 +126,7 @@ def create_default(tag: str) -> "GrammarElement":
89126
parent=None,
90127
tag=tag,
91128
property_is_composite="",
129+
property_view_style="",
92130
fields=[
93131
GrammarElementFieldString(
94132
parent=None,
@@ -135,18 +173,29 @@ def create_default_relations(
135173
),
136174
]
137175

176+
def is_field_multiline(self, field_name: str) -> bool:
177+
field_index = self.field_titles.index(field_name)
178+
try:
179+
title_field_index = self.field_titles.index("TITLE")
180+
if field_index <= title_field_index:
181+
return False
182+
except ValueError:
183+
pass
184+
return field_index >= self.content_field[1]
185+
138186
def get_multiline_field_index(self) -> int:
139-
multiline_field_index = self.content_field[1]
140-
assert multiline_field_index != -1
141-
return multiline_field_index
187+
return self.multiline_field_index
188+
189+
def get_view_style(self) -> Optional[str]:
190+
return self.property_view_style
142191

143192
def get_relation_types(self) -> List[str]:
144193
return list(
145194
map(lambda relation_: relation_.relation_type, self.relations)
146195
)
147196

148197
def get_field_titles(self) -> List[str]:
149-
return list(map(lambda field_: field_.title, self.fields))
198+
return self.field_titles
150199

151200
def get_tag_lower(self) -> str:
152201
return self.tag.lower()
@@ -284,6 +333,7 @@ def create_default(parent: Optional[SDocDocumentIF]) -> "DocumentGrammar":
284333
parent=None,
285334
tag="REQUIREMENT",
286335
property_is_composite="",
336+
property_view_style="",
287337
fields=fields,
288338
relations=[],
289339
)
@@ -344,13 +394,13 @@ def create_for_test_report(parent: SDocDocumentIF) -> "DocumentGrammar":
344394
parent=None,
345395
title=RequirementFieldName.STATUS,
346396
human_title=None,
347-
required="False",
397+
required="True",
348398
),
349399
GrammarElementFieldString(
350400
parent=None,
351401
title=RequirementFieldName.TITLE,
352402
human_title=None,
353-
required="False",
403+
required="True",
354404
),
355405
GrammarElementFieldString(
356406
parent=None,
@@ -363,6 +413,7 @@ def create_for_test_report(parent: SDocDocumentIF) -> "DocumentGrammar":
363413
parent=None,
364414
tag="TEST_RESULT",
365415
property_is_composite="",
416+
property_view_style="",
366417
fields=fields,
367418
relations=[],
368419
)
@@ -463,6 +514,7 @@ def create_default_text_element(
463514
parent=parent,
464515
tag="TEXT",
465516
property_is_composite="",
517+
property_view_style="",
466518
fields=fields,
467519
relations=[],
468520
)

0 commit comments

Comments
 (0)