StrictDoc Documentation
tests/unit/strictdoc/backend/sdoc/test_dsl_passthrough_grammar.py
Source file coverage
Path:
tests/unit/strictdoc/backend/sdoc/test_dsl_passthrough_grammar.py
Lines:
527
Non-empty lines:
444
Non-empty lines covered with requirements:
444 / 444 (100.0%)
Functions:
10
Functions covered by requirements:
10 / 10 (100.0%)
1
"""
2
@relation(SDOC-SRS-136, scope=file)
3
"""
4
 
5
import pytest
6
 
7
from strictdoc.backend.sdoc.models.document import SDocDocument
8
from strictdoc.backend.sdoc.models.node import SDocNode
9
from strictdoc.backend.sdoc.reader import SDReader
10
from strictdoc.backend.sdoc.validations.sdoc_validator import SDocValidator
11
from strictdoc.backend.sdoc.writer import SDWriter
12
from strictdoc.helpers.cast import assert_cast
13
from strictdoc.helpers.exception import StrictDocException
14
from tests.unit.helpers.fake_document_meta import create_fake_document_meta
15
 
16
 
17
def test_01_grammar_minimal_doc(default_project_config):
18
    input_sdoc = """
19
[DOCUMENT]
20
TITLE: Test Doc
21
 
22
[GRAMMAR]
23
ELEMENTS:
24
- TAG: TEXT
25
  FIELDS:
26
  - TITLE: STATEMENT
27
    TYPE: String
28
    REQUIRED: True
29
- TAG: LOW_LEVEL_REQUIREMENT
30
  FIELDS:
31
  - TITLE: STATEMENT
32
    TYPE: String
33
    REQUIRED: True
34
""".lstrip()
35
 
36
    expected_sdoc = """
37
[DOCUMENT]
38
TITLE: Test Doc
39
 
40
[GRAMMAR]
41
ELEMENTS:
42
- TAG: TEXT
43
  FIELDS:
44
  - TITLE: STATEMENT
45
    TYPE: String
46
    REQUIRED: True
47
- TAG: LOW_LEVEL_REQUIREMENT
48
  FIELDS:
49
  - TITLE: STATEMENT
50
    TYPE: String
51
    REQUIRED: True
52
""".lstrip()
53
    reader = SDReader()
54
 
55
    document = reader.read(input_sdoc)
56
    assert isinstance(document, SDocDocument)
57
 
58
    writer = SDWriter(default_project_config)
59
    output = writer.write(document)
60
 
61
    assert expected_sdoc == output
62
 
63
 
64
def test_10_grammar_single_choice(default_project_config):
65
    input_sdoc = """
66
[DOCUMENT]
67
TITLE: Test Doc
68
 
69
[GRAMMAR]
70
ELEMENTS:
71
- TAG: TEXT
72
  FIELDS:
73
  - TITLE: STATEMENT
74
    TYPE: String
75
    REQUIRED: True
76
- TAG: LOW_LEVEL_REQUIREMENT
77
  FIELDS:
78
  - TITLE: SINGLE_CHOICE_FIELD
79
    TYPE: SingleChoice(A, B, C)
80
    REQUIRED: True
81
  - TITLE: SINGLE_CHOICE_FIELD_2
82
    TYPE: SingleChoice(Test/Hardware, Test/Software)
83
    REQUIRED: True
84
  - TITLE: SINGLE_CHOICE_FIELD_3
85
    TYPE: SingleChoice(Hardware test, Software test)
86
    REQUIRED: True
87
  - TITLE: SINGLE_CHOICE_FIELD_4
88
    TYPE: SingleChoice("A(B)", "B(C)")
89
    REQUIRED: True
90
  - TITLE: STATEMENT
91
    TYPE: String
92
    REQUIRED: False
93
 
94
[LOW_LEVEL_REQUIREMENT]
95
SINGLE_CHOICE_FIELD: A
96
SINGLE_CHOICE_FIELD_2: Test/Hardware
97
SINGLE_CHOICE_FIELD_3: Hardware test
98
SINGLE_CHOICE_FIELD_4: A(B)
99
""".lstrip()
100
 
101
    reader = SDReader()
102
 
103
    document = reader.read(input_sdoc)
104
    assert isinstance(document, SDocDocument)
105
 
106
    assert len(document.section_contents) == 1
107
    field_4 = document.grammar.elements_by_type["LOW_LEVEL_REQUIREMENT"].fields[
108
        3
109
    ]
110
    assert field_4.options == ["A(B)", "B(C)"]
111
 
112
    writer = SDWriter(default_project_config)
113
    output = writer.write(document)
114
 
115
    assert input_sdoc == output
116
 
117
 
118
def test_15_grammar_single_choice_with_branches_but_no_quotes_raises_exception():
119
    input_sdoc = """
120
[DOCUMENT]
121
TITLE: Test Doc
122
 
123
[GRAMMAR]
124
ELEMENTS:
125
- TAG: TEXT
126
  FIELDS:
127
  - TITLE: STATEMENT
128
    TYPE: String
129
    REQUIRED: True
130
- TAG: LOW_LEVEL_REQUIREMENT
131
  FIELDS:
132
  - TITLE: SINGLE_CHOICE_FIELD
133
    TYPE: SingleChoice(A(B))
134
    REQUIRED: True
135
  - TITLE: STATEMENT
136
    TYPE: String
137
    REQUIRED: False
138
""".lstrip()
139
 
140
    reader = SDReader()
141
 
142
    with pytest.raises(StrictDocException):
143
        _ = reader.read(input_sdoc)
144
 
145
 
146
def test_16_grammar_single_choice_with_unmatched_quotes_raises_exception():
147
    input_sdoc = """
148
[DOCUMENT]
149
TITLE: Test Doc
150
 
151
[GRAMMAR]
152
ELEMENTS:
153
- TAG: TEXT
154
  FIELDS:
155
  - TITLE: STATEMENT
156
    TYPE: String
157
    REQUIRED: True
158
- TAG: LOW_LEVEL_REQUIREMENT
159
  FIELDS:
160
  - TITLE: SINGLE_CHOICE_FIELD
161
    TYPE: SingleChoice("A)
162
    REQUIRED: True
163
  - TITLE: STATEMENT
164
    TYPE: String
165
    REQUIRED: False
166
""".lstrip()
167
 
168
    reader = SDReader()
169
 
170
    with pytest.raises(StrictDocException):
171
        _ = reader.read(input_sdoc)
172
 
173
 
174
def test_152_grammar_multiple_choice(default_project_config):
175
    input_sdoc = """\
176
[DOCUMENT]
177
TITLE: Test Doc
178
 
179
[GRAMMAR]
180
ELEMENTS:
181
- TAG: TEXT
182
  FIELDS:
183
  - TITLE: STATEMENT
184
    TYPE: String
185
    REQUIRED: True
186
- TAG: LOW_LEVEL_REQUIREMENT
187
  FIELDS:
188
  - TITLE: MULTIPLE_CHOICE_FIELD
189
    TYPE: MultipleChoice(A, B, C)
190
    REQUIRED: True
191
  - TITLE: MULTIPLE_CHOICE_FIELD_2
192
    TYPE: MultipleChoice(Review, Test/Hardware)
193
    REQUIRED: True
194
  - TITLE: MULTIPLE_CHOICE_FIELD_3
195
    TYPE: MultipleChoice(Review of design, Hardware test)
196
    REQUIRED: True
197
  - TITLE: MULTIPLE_CHOICE_FIELD_4
198
    TYPE: MultipleChoice(review_of_design, hardware_test)
199
    REQUIRED: True
200
  - TITLE: MULTIPLE_CHOICE_FIELD_5
201
    TYPE: MultipleChoice(review-of-design, hardware-test)
202
    REQUIRED: True
203
  - TITLE: STATEMENT
204
    TYPE: String
205
    REQUIRED: False
206
 
207
[LOW_LEVEL_REQUIREMENT]
208
MULTIPLE_CHOICE_FIELD: A, C
209
MULTIPLE_CHOICE_FIELD_2: Review, Test/Hardware
210
MULTIPLE_CHOICE_FIELD_3: Review of design, Hardware test
211
MULTIPLE_CHOICE_FIELD_4: review_of_design, hardware_test
212
MULTIPLE_CHOICE_FIELD_5: review-of-design, hardware-test
213
"""
214
 
215
    reader = SDReader()
216
 
217
    document = reader.read(input_sdoc)
218
    assert isinstance(document, SDocDocument)
219
 
220
    document.meta = create_fake_document_meta()
221
    SDocValidator.validate_document(document)
222
    SDocValidator.validate_node(
223
        assert_cast(document.section_contents[0], SDocNode),
224
        document.grammar,
225
        "fake.path.sdoc",
226
        auto_uid_mode=False,
227
    )
228
 
229
    writer = SDWriter(default_project_config)
230
    output = writer.write(document)
231
 
232
    assert input_sdoc == output
233
 
234
 
235
def test_153_grammar_tag(default_project_config):
236
    input_sdoc = """
237
[DOCUMENT]
238
TITLE: Test Doc
239
 
240
[GRAMMAR]
241
ELEMENTS:
242
- TAG: TEXT
243
  FIELDS:
244
  - TITLE: STATEMENT
245
    TYPE: String
246
    REQUIRED: True
247
- TAG: LOW_LEVEL_REQUIREMENT
248
  FIELDS:
249
  - TITLE: TAG_FIELD
250
    TYPE: Tag
251
    REQUIRED: True
252
  - TITLE: STATEMENT
253
    TYPE: String
254
    REQUIRED: False
255
 
256
[LOW_LEVEL_REQUIREMENT]
257
TAG_FIELD: A, C
258
""".lstrip()
259
 
260
    expected_sdoc = """
261
[DOCUMENT]
262
TITLE: Test Doc
263
 
264
[GRAMMAR]
265
ELEMENTS:
266
- TAG: TEXT
267
  FIELDS:
268
  - TITLE: STATEMENT
269
    TYPE: String
270
    REQUIRED: True
271
- TAG: LOW_LEVEL_REQUIREMENT
272
  FIELDS:
273
  - TITLE: TAG_FIELD
274
    TYPE: Tag
275
    REQUIRED: True
276
  - TITLE: STATEMENT
277
    TYPE: String
278
    REQUIRED: False
279
 
280
[LOW_LEVEL_REQUIREMENT]
281
TAG_FIELD: A, C
282
""".lstrip()
283
 
284
    reader = SDReader()
285
 
286
    document = reader.read(input_sdoc)
287
    assert isinstance(document, SDocDocument)
288
 
289
    writer = SDWriter(default_project_config)
290
    output = writer.write(document)
291
 
292
    assert expected_sdoc == output
293
 
294
 
295
def test_154_grammar_multiline_custom_field(default_project_config):
296
    input_sdoc = """
297
[DOCUMENT]
298
TITLE: Test Doc
299
 
300
[GRAMMAR]
301
ELEMENTS:
302
- TAG: TEXT
303
  FIELDS:
304
  - TITLE: STATEMENT
305
    TYPE: String
306
    REQUIRED: True
307
- TAG: REQUIREMENT
308
  FIELDS:
309
  - TITLE: MY_FIELD
310
    TYPE: String
311
    REQUIRED: True
312
  - TITLE: STATEMENT
313
    TYPE: String
314
    REQUIRED: False
315
 
316
[REQUIREMENT]
317
MY_FIELD: >>>
318
Some text here...
319
Some text here...
320
Some text here...
321
<<<
322
""".lstrip()
323
 
324
    expected_sdoc = """
325
[DOCUMENT]
326
TITLE: Test Doc
327
 
328
[GRAMMAR]
329
ELEMENTS:
330
- TAG: TEXT
331
  FIELDS:
332
  - TITLE: STATEMENT
333
    TYPE: String
334
    REQUIRED: True
335
- TAG: REQUIREMENT
336
  FIELDS:
337
  - TITLE: MY_FIELD
338
    TYPE: String
339
    REQUIRED: True
340
  - TITLE: STATEMENT
341
    TYPE: String
342
    REQUIRED: False
343
 
344
[REQUIREMENT]
345
MY_FIELD: >>>
346
Some text here...
347
Some text here...
348
Some text here...
349
<<<
350
""".lstrip()
351
 
352
    reader = SDReader()
353
 
354
    document = reader.read(input_sdoc)
355
    assert isinstance(document, SDocDocument)
356
 
357
    writer = SDWriter(default_project_config)
358
    output = writer.write(document)
359
 
360
    assert expected_sdoc == output
361
 
362
 
363
def test_170_grammar_relations(default_project_config):
364
    input_sdoc = """
365
[DOCUMENT]
366
TITLE: Test Doc
367
 
368
[GRAMMAR]
369
ELEMENTS:
370
- TAG: TEXT
371
  FIELDS:
372
  - TITLE: STATEMENT
373
    TYPE: String
374
    REQUIRED: True
375
- TAG: LOW_LEVEL_REQUIREMENT
376
  FIELDS:
377
  - TITLE: STATEMENT
378
    TYPE: String
379
    REQUIRED: True
380
  RELATIONS:
381
  - TYPE: Parent
382
  - TYPE: Parent
383
    ROLE: Refines
384
  - TYPE: Child
385
    ROLE: Refined_by
386
 
387
[LOW_LEVEL_REQUIREMENT]
388
STATEMENT: This is a statement.
389
""".lstrip()
390
 
391
    reader = SDReader()
392
 
393
    document = reader.read(input_sdoc)
394
    assert isinstance(document, SDocDocument)
395
 
396
    writer = SDWriter(default_project_config)
397
    output = writer.write(document)
398
 
399
    assert input_sdoc == output
400
 
401
 
402
def test_180_additional_field_in_grammar():
403
    input_sdoc = """
404
[DOCUMENT]
405
TITLE: Test Document
406
 
407
[GRAMMAR]
408
ELEMENTS:
409
- TAG: REQUIREMENT
410
  FIELDS:
411
  - TITLE: UID
412
    TYPE: String
413
    REQUIRED: False
414
  - TITLE: LEVEL
415
    TYPE: String
416
    REQUIRED: False
417
  - TITLE: STATUS
418
    TYPE: String
419
    REQUIRED: False
420
  - TITLE: TAGS
421
    TYPE: String
422
    REQUIRED: False
423
  - TITLE: TITLE
424
    TYPE: String
425
    REQUIRED: False
426
  - TITLE: STATEMENT
427
    TYPE: String
428
    REQUIRED: False
429
  - TITLE: RATIONALE
430
    TYPE: String
431
    REQUIRED: False
432
  - TITLE: COMMENT
433
    TYPE: String
434
    REQUIRED: False
435
  - TITLE: META_TEST
436
    TYPE: String
437
    REQUIRED: False
438
 
439
[REQUIREMENT]
440
UID: A-1
441
STATEMENT: >>>
442
the foo must bar
443
<<<
444
COMMENT: >>>
445
Comment
446
<<<
447
META_TEST: >>>
448
Yes
449
<<<
450
    """.lstrip()
451
 
452
    reader = SDReader()
453
 
454
    document = reader.read(input_sdoc)
455
 
456
    requirement = document.section_contents[0]
457
    assert isinstance(requirement, SDocNode)
458
    # FIXME: More robust test.
459
    for _, value in requirement.enumerate_meta_fields():
460
        assert value.get_text_value() is not None
461
 
462
 
463
def test_190_element_properties(default_project_config):
464
    input_sdoc = """\
465
[DOCUMENT]
466
TITLE: Test Document
467
 
468
[GRAMMAR]
469
ELEMENTS:
470
- TAG: SECTION
471
  PROPERTIES:
472
    IS_COMPOSITE: True
473
  FIELDS:
474
  - TITLE: UID
475
    TYPE: String
476
    REQUIRED: False
477
  - TITLE: TITLE
478
    TYPE: String
479
    REQUIRED: False
480
- TAG: TEXT
481
  PROPERTIES:
482
    IS_COMPOSITE: False
483
    VIEW_STYLE: Plain
484
  FIELDS:
485
  - TITLE: UID
486
    TYPE: String
487
    REQUIRED: False
488
  - TITLE: STATEMENT
489
    TYPE: String
490
    REQUIRED: False
491
- TAG: REQUIREMENT
492
  PROPERTIES:
493
    IS_COMPOSITE: True
494
  FIELDS:
495
  - TITLE: UID
496
    TYPE: String
497
    REQUIRED: False
498
  - TITLE: TITLE
499
    TYPE: String
500
    REQUIRED: False
501
  - TITLE: STATEMENT
502
    TYPE: String
503
    REQUIRED: False
504
  - TITLE: RATIONALE
505
    TYPE: String
506
    REQUIRED: False
507
  - TITLE: COMMENT
508
    TYPE: String
509
    REQUIRED: False
510
 
511
[[REQUIREMENT]]
512
UID: A-1
513
STATEMENT: >>>
514
the foo must bar
515
<<<
516
 
517
[[/REQUIREMENT]]
518
"""
519
 
520
    reader = SDReader()
521
 
522
    document = reader.read(input_sdoc)
523
    assert isinstance(document, SDocDocument)
524
 
525
    writer = SDWriter(default_project_config)
526
    output = writer.write(document)
527
    assert input_sdoc == output