Path:
strictdoc/backend/sdoc/models/document_grammar.py
Lines:
405
Non-empty lines:
367
Non-empty lines covered with requirements:
367 / 367 (100.0%)
Functions:
14
Functions covered by requirements:
14 / 14 (100.0%)
1
"""2
@relation(SDOC-SRS-19, scope=file)3
"""4
5
from typing import Dict, List, Optional, Set
6
7
from strictdoc.backend.sdoc.models.grammar_element import (
8
GrammarElement,
9
GrammarElementFieldString,
10
GrammarElementFieldType,
11
)12
from strictdoc.backend.sdoc.models.model import (
13
RequirementFieldName,
14
SDocDocumentIF,
15
SDocGrammarIF,
16
)17
18
19
class DocumentGrammar(SDocGrammarIF):
20
def __init__(
21
self,
22
parent: Optional[SDocDocumentIF],
23
elements: List[GrammarElement],
24
import_from_file: Optional[str] = None,
25
) -> None:
26
self.parent: Optional[SDocDocumentIF] = parent
27
self.elements: List[GrammarElement] = elements
28
29
self.registered_elements: Set[str] = set()
30
self.elements_by_type: Dict[str, GrammarElement] = {}
31
32
self.update_with_elements(elements)
33
34
# The textX parser passes an empty string instead of None when35
# import_from_file is not provided in input.36
if import_from_file is not None and len(import_from_file) == 0:
37
import_from_file = None
38
self.import_from_file: Optional[str] = import_from_file
39
40
self.is_default = False
41
42
self.ng_line_start: Optional[int] = None
43
self.ng_col_start: Optional[int] = None
44
45
@staticmethod46
def create_default(
47
parent: Optional[SDocDocumentIF],
48
enable_mid: bool = False,
49
include_child_relation: bool = False,
50
) -> "DocumentGrammar":
51
"""
52
@relation(SDOC-SRS-93, scope=function)53
"""54
55
text_element: GrammarElement = (
56
DocumentGrammar.create_default_text_element(enable_mid=enable_mid)
57
)58
59
# @relation(SDOC-SRS-132, scope=range_start)60
fields: List[GrammarElementFieldType] = []
61
62
if enable_mid:
63
fields.append(
64
GrammarElementFieldString(
65
parent=None,
66
title=RequirementFieldName.MID,
67
human_title=None,
68
required="False",
69
)70
)71
72
fields.extend(
73
[74
GrammarElementFieldString(
75
parent=None,
76
title=RequirementFieldName.UID,
77
human_title=None,
78
required="False",
79
),80
GrammarElementFieldString(
81
parent=None,
82
title=RequirementFieldName.LEVEL,
83
human_title=None,
84
required="False",
85
),86
GrammarElementFieldString(
87
parent=None,
88
title=RequirementFieldName.STATUS,
89
human_title=None,
90
required="False",
91
),92
GrammarElementFieldString(
93
parent=None,
94
title=RequirementFieldName.TAGS,
95
human_title=None,
96
required="False",
97
),98
GrammarElementFieldString(
99
parent=None,
100
title=RequirementFieldName.TITLE,
101
human_title=None,
102
required="False",
103
),104
GrammarElementFieldString(
105
parent=None,
106
title=RequirementFieldName.STATEMENT,
107
human_title=None,
108
required="False",
109
),110
GrammarElementFieldString(
111
parent=None,
112
title=RequirementFieldName.RATIONALE,
113
human_title=None,
114
required="False",
115
),116
GrammarElementFieldString(
117
parent=None,
118
title=RequirementFieldName.COMMENT,
119
human_title=None,
120
required="False",
121
),122
]123
)124
125
requirement_element = GrammarElement(
126
parent=None,
127
tag="REQUIREMENT",
128
property_is_composite="",
129
property_prefix="",
130
property_view_style="",
131
fields=fields,
132
relations=[],
133
)134
# @relation(SDOC-SRS-132, scope=range_end)135
136
requirement_element.relations = GrammarElement.create_default_relations(
137
requirement_element,
138
include_child=include_child_relation,
139
)140
141
elements: List[GrammarElement] = []
142
143
section_element: GrammarElement = (
144
DocumentGrammar.create_default_section_element(
145
enable_mid=enable_mid
146
)147
)148
elements.append(section_element)
149
150
elements.append(text_element)
151
elements.append(requirement_element)
152
153
grammar = DocumentGrammar(
154
parent=parent, elements=elements, import_from_file=None
155
)156
grammar.is_default = True
157
text_element.parent = grammar
158
requirement_element.parent = grammar
159
160
return grammar
161
162
@staticmethod163
def create_for_test_report(parent: SDocDocumentIF) -> "DocumentGrammar":
164
section_element: GrammarElement = (
165
DocumentGrammar.create_default_section_element(
166
parent=None, enable_mid=parent.config.enable_mid == True
167
)168
)169
text_element: GrammarElement = (
170
DocumentGrammar.create_default_text_element(
171
parent=None, enable_mid=parent.config.enable_mid == True
172
)173
)174
175
fields: List[GrammarElementFieldType] = [
176
GrammarElementFieldString(
177
parent=None,
178
title=RequirementFieldName.UID,
179
human_title=None,
180
required="False",
181
),182
GrammarElementFieldString(
183
parent=None,
184
title="TEST_PATH",
185
human_title=None,
186
required="False",
187
),188
GrammarElementFieldString(
189
parent=None,
190
title="TEST_FUNCTION",
191
human_title=None,
192
required="False",
193
),194
GrammarElementFieldString(
195
parent=None,
196
title="DURATION",
197
human_title=None,
198
required="False",
199
),200
GrammarElementFieldString(
201
parent=None,
202
title=RequirementFieldName.STATUS,
203
human_title=None,
204
required="True",
205
),206
GrammarElementFieldString(
207
parent=None,
208
title=RequirementFieldName.TITLE,
209
human_title=None,
210
required="True",
211
),212
GrammarElementFieldString(
213
parent=None,
214
title=RequirementFieldName.STATEMENT,
215
human_title=None,
216
required="False",
217
),218
]219
requirement_element = GrammarElement(
220
parent=None,
221
tag="TEST_RESULT",
222
property_is_composite="",
223
property_prefix="",
224
property_view_style="",
225
fields=fields,
226
relations=[],
227
)228
229
requirement_element.relations = GrammarElement.create_default_relations(
230
requirement_element231
)232
233
elements: List[GrammarElement] = [
234
section_element,
235
text_element,
236
requirement_element,
237
]238
grammar = DocumentGrammar(
239
parent=parent, elements=elements, import_from_file=None
240
)241
grammar.is_default = True
242
section_element.parent = grammar
243
text_element.parent = grammar
244
requirement_element.parent = grammar
245
246
return grammar
247
248
def get_element_by_mid(self, element_mid: str) -> GrammarElement:
249
for element_ in self.elements:
250
if element_.mid == element_mid:
251
return element_
252
raise AssertionError(
253
f"Could not find a grammar element with MID: {element_mid}"
254
)255
256
def dump_fields(self, node_type: str) -> str:
257
return ", ".join(
258
list(
259
map(
260
lambda g: g.title,
261
self.elements_by_type[node_type].fields,
262
)263
)264
)265
266
def has_text_element(self) -> bool:
267
for element_ in self.elements:
268
if element_.tag == "TEXT":
269
return True
270
return False
271
272
def add_element_first(self, element: GrammarElement) -> None:
273
self.elements.insert(0, element)
274
self.elements_by_type[element.tag] = element
275
self.registered_elements.add(element.tag)
276
self.is_default = False
277
278
def update_element(
279
self, existing_element: GrammarElement, updated_element: GrammarElement
280
) -> None:
281
element_index = self.elements.index(existing_element)
282
self.elements[element_index] = updated_element
283
self.elements_by_type[updated_element.tag] = updated_element
284
self.is_default = False
285
286
def update_with_elements(self, elements: List[GrammarElement]) -> None:
287
# When elements are created by code, not by textX, it is convenient288
# if their .parent is set here automatically.289
for element_ in elements:
290
element_.parent = self
291
292
registered_elements: Set[str] = set()
293
elements_by_type: Dict[str, GrammarElement] = {}
294
for element in elements:
295
registered_elements.add(element.tag)
296
elements_by_type[element.tag] = element
297
298
self.elements = elements
299
self.registered_elements = registered_elements
300
self.elements_by_type = elements_by_type
301
302
@staticmethod303
def create_default_text_element(
304
parent: Optional["DocumentGrammar"] = None,
305
enable_mid: bool = False,
306
) -> GrammarElement:
307
fields: List[GrammarElementFieldType] = []
308
if enable_mid:
309
fields.append(
310
GrammarElementFieldString(
311
parent=None,
312
title=RequirementFieldName.MID,
313
human_title=None,
314
required="False",
315
)316
)317
fields.extend(
318
[319
GrammarElementFieldString(
320
parent=None,
321
title=RequirementFieldName.UID,
322
human_title=None,
323
required="False",
324
),325
GrammarElementFieldString(
326
parent=None,
327
title=RequirementFieldName.STATEMENT,
328
human_title=None,
329
required="True",
330
),331
]332
)333
text_element = GrammarElement(
334
parent=parent,
335
tag="TEXT",
336
property_is_composite="",
337
property_prefix="",
338
property_view_style="",
339
fields=fields,
340
relations=[],
341
)342
return text_element
343
344
@staticmethod345
def create_default_section_element(
346
parent: Optional["DocumentGrammar"] = None, enable_mid: bool = False
347
) -> GrammarElement:
348
fields: List[GrammarElementFieldType] = []
349
if enable_mid:
350
fields.append(
351
GrammarElementFieldString(
352
parent=None,
353
title=RequirementFieldName.MID,
354
human_title=None,
355
required="False",
356
)357
)358
fields.append(
359
GrammarElementFieldString(
360
parent=None,
361
title=RequirementFieldName.UID,
362
human_title=None,
363
required="False",
364
)365
)366
fields.append(
367
GrammarElementFieldString(
368
parent=None,
369
title=RequirementFieldName.LEVEL,
370
human_title=None,
371
required="False",
372
)373
)374
fields.append(
375
GrammarElementFieldString(
376
parent=None,
377
title=RequirementFieldName.PREFIX,
378
human_title=None,
379
required="False",
380
)381
)382
fields.append(
383
GrammarElementFieldString(
384
parent=None,
385
title=RequirementFieldName.TITLE,
386
human_title=None,
387
required="True",
388
),389
)390
section_element = GrammarElement(
391
parent=parent,
392
tag="SECTION",
393
property_is_composite="True",
394
property_prefix="",
395
property_view_style="",
396
fields=fields,
397
relations=[],
398
)399
return section_element
400
401
402
class DocumentGrammarWrapper:
403
def __init__(self, grammar: DocumentGrammar):
404
assert isinstance(grammar, DocumentGrammar), grammar
405
self.grammar: DocumentGrammar = grammar