Path:
tests/unit/strictdoc/backend/sdoc/test_dsl_passthrough.py
Lines:
1215
Non-empty lines:
879
Non-empty lines covered with requirements:
879 / 879 (100.0%)
Functions:
42
Functions covered by requirements:
42 / 42 (100.0%)
- "2.2. Identical SDoc content by import/export roundtrip" (REQUIREMENT)
- "2.2. Identical SDoc content by import/export roundtrip" (REQUIREMENT)
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.grammar_element import ReferenceType
9
from strictdoc.backend.sdoc.models.node import (
10
SDocNode,
11
)12
from strictdoc.backend.sdoc.models.reference import (
13
FileReference,
14
)15
from strictdoc.backend.sdoc.reader import SDReader
16
from strictdoc.backend.sdoc.writer import SDWriter
17
from strictdoc.helpers.exception import StrictDocException
18
19
20
def test_001_minimal_doc(default_project_config):
21
input_sdoc = """\
22
[DOCUMENT]23
TITLE: Test Doc24
25
[REQUIREMENT]26
STATEMENT: ...27
28
[REQUIREMENT]29
STATEMENT: ...30
31
[REQUIREMENT]32
STATEMENT: ...33
"""34
35
reader = SDReader()
36
37
document = reader.read(input_sdoc)
38
assert isinstance(document, SDocDocument)
39
40
writer = SDWriter(default_project_config)
41
output = writer.write(document)
42
43
assert input_sdoc == output
44
45
46
def test_002_minimal_req(default_project_config):
47
input_sdoc = """
48
[DOCUMENT]49
TITLE: Test Doc50
51
[REQUIREMENT]52
TITLE: Hello53
""".lstrip()
54
55
reader = SDReader()
56
57
document = reader.read(input_sdoc)
58
assert isinstance(document, SDocDocument)
59
60
writer = SDWriter(default_project_config)
61
output = writer.write(document)
62
63
assert input_sdoc == output
64
65
66
def test_005_requirement_UID_supports_special_characters(
67
default_project_config,
68
):69
input_sdoc = """
70
[DOCUMENT]71
TITLE: Test Doc72
73
[REQUIREMENT]74
UID: FOO-175
TITLE: Hello76
77
[REQUIREMENT]78
UID: FOO.179
TITLE: Hello80
81
[REQUIREMENT]82
UID: FOO/183
TITLE: Hello84
85
[REQUIREMENT]86
UID: FOO_187
TITLE: Hello88
89
[REQUIREMENT]90
UID: FOO 191
TITLE: Hello92
93
[REQUIREMENT]94
UID: FOO::195
TITLE: Hello96
""".lstrip()
97
98
reader = SDReader()
99
100
document = reader.read(input_sdoc)
101
assert isinstance(document, SDocDocument)
102
103
writer = SDWriter(default_project_config)
104
output = writer.write(document)
105
106
assert input_sdoc == output
107
108
109
def test_003_comments_01_several_comments(default_project_config):
110
input_sdoc = """
111
[DOCUMENT]112
TITLE: Test Doc113
114
[REQUIREMENT]115
TITLE: Hello116
COMMENT: Comment #1117
COMMENT: Comment #2118
COMMENT: Comment #3119
""".lstrip()
120
121
reader = SDReader()
122
123
document = reader.read(input_sdoc)
124
assert isinstance(document, SDocDocument)
125
126
writer = SDWriter(default_project_config)
127
output = writer.write(document)
128
129
assert input_sdoc == output
130
131
132
def test_004_several_tags(default_project_config):
133
input_sdoc = """
134
[DOCUMENT]135
TITLE: Test Doc136
137
[REQUIREMENT]138
TAGS: A, B, C, D139
TITLE: Hello140
""".lstrip()
141
142
reader = SDReader()
143
144
document = reader.read(input_sdoc)
145
assert isinstance(document, SDocDocument)
146
147
writer = SDWriter(default_project_config)
148
output = writer.write(document)
149
150
assert input_sdoc == output
151
152
153
def test_010_multiple_sections(default_project_config):
154
input_sdoc = """\
155
[DOCUMENT]156
TITLE: Test Doc157
158
[[SECTION]]159
TITLE: Test Section160
161
[REQUIREMENT]162
STATEMENT: >>>163
This is a statement 1164
This is a statement 2165
This is a statement 3166
<<<167
168
[[/SECTION]]169
170
[[SECTION]]171
TITLE: Test Section172
173
[REQUIREMENT]174
STATEMENT: >>>175
This is a statement 1176
This is a statement 2177
This is a statement 3178
<<<179
180
[[/SECTION]]181
"""182
183
reader = SDReader()
184
185
document = reader.read(input_sdoc)
186
assert isinstance(document, SDocDocument)
187
188
writer = SDWriter(default_project_config)
189
output = writer.write(document)
190
assert input_sdoc == output
191
192
193
def test_020_requirement_mid(default_project_config):
194
input_sdoc = """
195
[DOCUMENT]196
TITLE: Test Doc197
198
[GRAMMAR]199
ELEMENTS:200
- TAG: TEXT201
FIELDS:202
- TITLE: UID203
TYPE: String204
REQUIRED: False205
- TITLE: STATEMENT206
TYPE: String207
REQUIRED: True208
- TAG: REQUIREMENT209
FIELDS:210
- TITLE: MID211
TYPE: String212
REQUIRED: False213
- TITLE: STATEMENT214
TYPE: String215
REQUIRED: False216
217
[REQUIREMENT]218
MID: abcdef123456219
STATEMENT: >>>220
This is a statement 1221
This is a statement 2222
This is a statement 3223
<<<224
""".lstrip()
225
226
reader = SDReader()
227
228
document = reader.read(input_sdoc)
229
assert isinstance(document, SDocDocument)
230
231
writer = SDWriter(default_project_config)
232
output = writer.write(document)
233
assert input_sdoc == output
234
235
236
def test_021_section_and_document_mid(default_project_config):
237
input_sdoc = """
238
[DOCUMENT]239
MID: xyz09876240
TITLE: Test Doc241
OPTIONS:242
ENABLE_MID: True243
244
[[SECTION]]245
MID: abcdef123456246
TITLE: Test Section247
248
[[/SECTION]]249
""".lstrip()
250
251
reader = SDReader()
252
253
document = reader.read(input_sdoc)
254
assert isinstance(document, SDocDocument)
255
256
writer = SDWriter(default_project_config)
257
output = writer.write(document)
258
259
assert input_sdoc == output
260
261
262
def test_022_requirement_uid_and_link(default_project_config):
263
input_sdoc = """
264
[DOCUMENT]265
TITLE: Test Doc266
267
[REQUIREMENT]268
UID: With spaces and (_-.) and non latin 特点269
STATEMENT: >>>270
This is a statement.271
272
[TEXT]273
STATEMENT: >>>274
[LINK: With spaces and (_-.) and non latin 特点]275
<<<276
""".lstrip()
277
278
reader = SDReader()
279
280
document = reader.read(input_sdoc)
281
assert isinstance(document, SDocDocument)
282
283
writer = SDWriter(default_project_config)
284
output = writer.write(document)
285
286
assert input_sdoc == output
287
288
289
def test_030_multiline_statement(default_project_config):
290
input_sdoc = """
291
[DOCUMENT]292
TITLE: Test Doc293
294
[[SECTION]]295
TITLE: Test Section296
297
[REQUIREMENT]298
STATEMENT: >>>299
This is a statement 1300
This is a statement 2301
This is a statement 3302
<<<303
304
[[/SECTION]]305
""".lstrip()
306
307
reader = SDReader()
308
309
document = reader.read(input_sdoc)
310
assert isinstance(document, SDocDocument)
311
312
assert isinstance(
313
document.section_contents[0].section_contents[0], SDocNode
314
)315
requirement_1 = document.section_contents[0].section_contents[0]
316
assert (
317
requirement_1.reserved_statement
318
== "This is a statement 1\nThis is a statement 2\nThis is a statement 3\n"
319
)320
321
writer = SDWriter(default_project_config)
322
output = writer.write(document)
323
324
assert input_sdoc == output
325
326
327
def test_036_rationale_single_line(default_project_config):
328
input_sdoc = """
329
[DOCUMENT]330
TITLE: Test Doc331
332
[[SECTION]]333
TITLE: Test Section334
335
[REQUIREMENT]336
STATEMENT: Some statement337
RATIONALE: This is a Rationale338
339
[[/SECTION]]340
""".lstrip()
341
342
reader = SDReader()
343
344
document = reader.read(input_sdoc)
345
assert isinstance(document, SDocDocument)
346
347
writer = SDWriter(default_project_config)
348
output = writer.write(document)
349
350
assert input_sdoc == output
351
352
assert isinstance(
353
document.section_contents[0].section_contents[0], SDocNode
354
)355
requirement_1 = document.section_contents[0].section_contents[0]
356
assert requirement_1.rationale == "This is a Rationale"
357
358
359
def test_037_rationale_multi_line(default_project_config):
360
input_sdoc = """
361
[DOCUMENT]362
TITLE: Test Doc363
364
[[SECTION]]365
TITLE: Test Section366
367
[REQUIREMENT]368
STATEMENT: Some statement369
RATIONALE: >>>370
This is a Rationale line 1371
This is a Rationale line 2372
This is a Rationale line 3373
<<<374
375
[[/SECTION]]376
""".lstrip()
377
378
reader = SDReader()
379
380
document = reader.read(input_sdoc)
381
assert isinstance(document, SDocDocument)
382
383
writer = SDWriter(default_project_config)
384
output = writer.write(document)
385
386
assert input_sdoc == output
387
388
assert isinstance(
389
document.section_contents[0].section_contents[0], SDocNode
390
)391
requirement_1 = document.section_contents[0].section_contents[0]
392
assert requirement_1.rationale == (
393
"This is a Rationale line 1\n"
394
"This is a Rationale line 2\n"
395
"This is a Rationale line 3\n"
396
)397
398
399
# This test is needed to make sure that the grammar details related400
# to the difference of parting single vs multiline strings are covered.401
def test_050_requirement_single_line_statement_one_symbol(
402
default_project_config,
403
):404
input_sdoc = """
405
[DOCUMENT]406
TITLE: Test Doc407
408
[REQUIREMENT]409
STATEMENT: 1410
""".lstrip()
411
412
reader = SDReader()
413
414
document = reader.read(input_sdoc)
415
assert isinstance(document, SDocDocument)
416
417
document: SDocDocument = reader.read(input_sdoc)
418
requirement = document.section_contents[0]
419
assert requirement.reserved_statement == "1"
420
421
writer = SDWriter(default_project_config)
422
output = writer.write(document)
423
424
assert input_sdoc == output
425
426
427
def test_060_file_ref(default_project_config):
428
input_sdoc = """
429
[DOCUMENT]430
TITLE: Test Doc431
432
[REQUIREMENT]433
STATEMENT: ...434
RELATIONS:435
- TYPE: File436
VALUE: /tmp/sample.cpp437
""".lstrip()
438
439
reader = SDReader()
440
441
document = reader.read(input_sdoc)
442
assert isinstance(document, SDocDocument)
443
444
requirement: SDocNode = document.section_contents[0]
445
relations = requirement.relations
446
assert len(relations) == 1
447
448
reference: FileReference = relations[0]
449
assert isinstance(reference, FileReference)
450
assert reference.ref_type == ReferenceType.FILE
451
assert reference.g_file_entry.g_file_path == "/tmp/sample.cpp"
452
453
writer = SDWriter(default_project_config)
454
output = writer.write(document)
455
456
assert input_sdoc == output
457
458
459
def test_070_document_config_version(default_project_config):
460
input_sdoc = """
461
[DOCUMENT]462
TITLE: Test Doc463
VERSION: 0.0.1464
465
[REQUIREMENT]466
STATEMENT: ...467
""".lstrip()
468
469
reader = SDReader()
470
471
document = reader.read(input_sdoc)
472
assert isinstance(document, SDocDocument)
473
474
document: SDocDocument = reader.read(input_sdoc)
475
assert document.config.version == "0.0.1"
476
477
writer = SDWriter(default_project_config)
478
output = writer.write(document)
479
480
assert input_sdoc == output
481
482
483
def test_071_document_config_number(default_project_config):
484
input_sdoc = """
485
[DOCUMENT]486
TITLE: Test Doc487
UID: SDOC-01488
489
[REQUIREMENT]490
STATEMENT: ...491
""".lstrip()
492
493
reader = SDReader()
494
495
document = reader.read(input_sdoc)
496
assert isinstance(document, SDocDocument)
497
498
document: SDocDocument = reader.read(input_sdoc)
499
assert document.config.uid == "SDOC-01"
500
501
writer = SDWriter(default_project_config)
502
output = writer.write(document)
503
504
assert input_sdoc == output
505
506
507
def test_072_document_config_classification(default_project_config):
508
input_sdoc = """
509
[DOCUMENT]510
TITLE: Test Doc511
UID: SDOC-01512
VERSION: 0.0.1513
CLASSIFICATION: Restricted514
515
[REQUIREMENT]516
STATEMENT: ...517
""".lstrip()
518
519
reader = SDReader()
520
521
document = reader.read(input_sdoc)
522
assert isinstance(document, SDocDocument)
523
524
document: SDocDocument = reader.read(input_sdoc)
525
assert document.config.classification == "Restricted"
526
527
writer = SDWriter(default_project_config)
528
output = writer.write(document)
529
530
assert input_sdoc == output
531
532
533
def test_073_document_config_requirement_prefix(default_project_config):
534
input_sdoc = """
535
[DOCUMENT]536
TITLE: Test Doc537
UID: SDOC-01538
VERSION: 0.0.1539
PREFIX: DOC-540
541
[REQUIREMENT]542
STATEMENT: ...543
""".lstrip()
544
545
reader = SDReader()
546
547
document = reader.read(input_sdoc)
548
assert isinstance(document, SDocDocument)
549
550
document: SDocDocument = reader.read(input_sdoc)
551
assert document.config.requirement_prefix == "DOC-"
552
553
writer = SDWriter(default_project_config)
554
output = writer.write(document)
555
556
assert input_sdoc == output
557
558
559
def test_074_document_config_metadata(default_project_config):
560
input_sdoc = """
561
[DOCUMENT]562
TITLE: Test Doc563
UID: SDOC-01564
VERSION: 0.0.1565
METADATA:566
AUTHOR: James T. Kirk567
CHECKED-BY: Chuck Norris568
APPROVED-BY: Wile E. Coyote569
570
[REQUIREMENT]571
UID: FOO572
""".lstrip()
573
574
reader = SDReader()
575
576
document = reader.read(input_sdoc)
577
assert isinstance(document, SDocDocument)
578
579
writer = SDWriter(default_project_config)
580
output = writer.write(document)
581
582
assert input_sdoc == output
583
584
585
def test_090_document_config_all_fields(default_project_config):
586
input_sdoc = """
587
[DOCUMENT]588
TITLE: Test Doc589
UID: SDOC-01590
VERSION: 0.0.1591
CLASSIFICATION: Restricted592
ROOT: True593
OPTIONS:594
MARKUP: Text595
AUTO_LEVELS: Off596
LAYOUT: Website597
VIEW_STYLE: Table598
NODE_IN_TOC: True599
600
[[SECTION]]601
LEVEL: 123602
TITLE: "Section"603
604
[REQUIREMENT]605
LEVEL: 456606
STATEMENT: ABC607
608
[[/SECTION]]609
""".lstrip()
610
611
reader = SDReader()
612
613
document = reader.read(input_sdoc)
614
assert isinstance(document, SDocDocument)
615
616
document: SDocDocument = reader.read(input_sdoc)
617
assert document.title == "Test Doc"
618
assert document.config.version == "0.0.1"
619
assert document.config.uid == "SDOC-01"
620
assert document.config.classification == "Restricted"
621
assert document.config.root is True
622
assert document.config.markup == "Text"
623
assert document.config.auto_levels is False
624
assert document.config.requirement_style == "Table"
625
assert document.config.requirement_in_toc == "True"
626
627
section = document.section_contents[0]
628
assert isinstance(section, SDocNode)
629
assert section.custom_level == "123"
630
631
requirement = section.section_contents[0]
632
assert isinstance(requirement, SDocNode)
633
assert requirement.custom_level == "456"
634
635
writer = SDWriter(default_project_config)
636
output = writer.write(document)
637
638
assert input_sdoc == output
639
640
641
def test_100_basic_test(default_project_config):
642
input_sdoc = """
643
[DOCUMENT]644
TITLE: Test Doc645
646
[[SECTION]]647
TITLE: Test Section648
649
[REQUIREMENT]650
TAGS: Tag 1, Tag 2, Tag 3651
STATEMENT: System shall do X652
COMMENT: This requirement is very important653
RELATIONS:654
- TYPE: File655
VALUE: /usr/local/bin/hexe656
- TYPE: File657
VALUE: /usr/local/bin/hexe658
- TYPE: File659
VALUE: /usr/local/bin/hexe660
661
[REQUIREMENT]662
UID: REQ-001663
STATUS: Draft664
TITLE: Optional title B665
STATEMENT: System shall do Y666
COMMENT: This requirement is very important667
668
[[/SECTION]]669
""".lstrip()
670
671
reader = SDReader()
672
673
document = reader.read(input_sdoc)
674
assert isinstance(document, SDocDocument)
675
676
assert isinstance(
677
document.section_contents[0].section_contents[0], SDocNode
678
)679
requirement_1 = document.section_contents[0].section_contents[0]
680
assert requirement_1.reserved_tags[0] == "Tag 1"
681
assert requirement_1.reserved_tags[1] == "Tag 2"
682
assert requirement_1.reserved_tags[2] == "Tag 3"
683
684
writer = SDWriter(default_project_config)
685
output = writer.write(document)
686
687
assert input_sdoc == output
688
689
690
def test_081_document_config_markup_not_specified(default_project_config):
691
input_sdoc = """
692
[DOCUMENT]693
TITLE: Test Doc694
VERSION: 0.0.1695
696
[REQUIREMENT]697
TITLE: ...698
""".lstrip()
699
700
reader = SDReader()
701
702
document = reader.read(input_sdoc)
703
assert isinstance(document, SDocDocument)
704
705
document: SDocDocument = reader.read(input_sdoc)
706
assert document.config.version == "0.0.1"
707
assert document.config.markup is None
708
709
writer = SDWriter(default_project_config)
710
output = writer.write(document)
711
712
assert input_sdoc == output
713
714
715
def test_081_document_config_markup_specified(default_project_config):
716
input_sdoc = """
717
[DOCUMENT]718
TITLE: Test Doc719
VERSION: 0.0.1720
OPTIONS:721
MARKUP: Text722
723
[REQUIREMENT]724
STATEMENT: ...725
""".lstrip()
726
727
reader = SDReader()
728
729
document = reader.read(input_sdoc)
730
assert isinstance(document, SDocDocument)
731
732
document: SDocDocument = reader.read(input_sdoc)
733
assert document.config.version == "0.0.1"
734
735
writer = SDWriter(default_project_config)
736
output = writer.write(document)
737
738
assert input_sdoc == output
739
740
741
def test_082_document_config_auto_levels_specified_to_false(
742
default_project_config,
743
):744
input_sdoc = """
745
[DOCUMENT]746
TITLE: Test Doc747
VERSION: 0.0.1748
OPTIONS:749
AUTO_LEVELS: Off750
""".lstrip()
751
752
reader = SDReader()
753
754
document = reader.read(input_sdoc)
755
assert isinstance(document, SDocDocument)
756
757
document: SDocDocument = reader.read(input_sdoc)
758
assert document.config.auto_levels is False
759
760
writer = SDWriter(default_project_config)
761
output = writer.write(document)
762
763
assert input_sdoc == output
764
765
766
def test_083_requirement_level(default_project_config):
767
input_sdoc = """
768
[DOCUMENT]769
TITLE: Test Doc770
VERSION: 0.0.1771
OPTIONS:772
AUTO_LEVELS: Off773
774
[[SECTION]]775
LEVEL: 123776
TITLE: "Section"777
778
[REQUIREMENT]779
LEVEL: 456780
STATEMENT: ABC781
782
[[/SECTION]]783
""".lstrip()
784
785
reader = SDReader()
786
787
document = reader.read(input_sdoc)
788
assert isinstance(document, SDocDocument)
789
790
document: SDocDocument = reader.read(input_sdoc)
791
assert document.config.auto_levels is False
792
section: SDocNode = document.section_contents[0]
793
assert section.custom_level == "123"
794
795
requirement = section.section_contents[0]
796
assert isinstance(requirement, SDocNode)
797
assert requirement.custom_level == "456"
798
799
writer = SDWriter(default_project_config)
800
output = writer.write(document)
801
802
assert input_sdoc == output
803
804
805
def test_085_options_requirement_style(default_project_config):
806
input_sdoc = """
807
[DOCUMENT]808
TITLE: Test Doc809
VERSION: 0.0.1810
OPTIONS:811
VIEW_STYLE: Table812
""".lstrip()
813
814
reader = SDReader()
815
816
document = reader.read(input_sdoc)
817
assert isinstance(document, SDocDocument)
818
819
document: SDocDocument = reader.read(input_sdoc)
820
assert document.config.requirement_style == "Table"
821
822
writer = SDWriter(default_project_config)
823
output = writer.write(document)
824
825
assert input_sdoc == output
826
827
828
def test_087_options_requirement_in_toc(default_project_config):
829
input_sdoc = """
830
[DOCUMENT]831
TITLE: Test Doc832
VERSION: 0.0.1833
OPTIONS:834
NODE_IN_TOC: True835
""".lstrip()
836
837
reader = SDReader()
838
839
document = reader.read(input_sdoc)
840
assert isinstance(document, SDocDocument)
841
842
document: SDocDocument = reader.read(input_sdoc)
843
assert document.config.requirement_in_toc == "True"
844
845
writer = SDWriter(default_project_config)
846
output = writer.write(document)
847
848
assert input_sdoc == output
849
850
851
def test_089_document_config_use_mid(default_project_config):
852
input_sdoc = """
853
[DOCUMENT]854
MID: foobar855
TITLE: Test Doc856
OPTIONS:857
ENABLE_MID: True858
""".lstrip()
859
860
reader = SDReader()
861
862
document = reader.read(input_sdoc)
863
assert isinstance(document, SDocDocument)
864
865
document: SDocDocument = reader.read(input_sdoc)
866
assert document.config.enable_mid is True
867
868
writer = SDWriter(default_project_config)
869
output = writer.write(document)
870
871
assert input_sdoc == output
872
873
874
def test_090_byte_order_mark_symbol_does_not_cause_parsing_errors():
875
input_sdoc = (
876
"\ufeff"
877
"""\
878
[DOCUMENT]879
TITLE: Test Doc880
"""881
)882
883
reader = SDReader()
884
885
document = reader.read(input_sdoc)
886
assert isinstance(document, SDocDocument)
887
888
889
def test__validation__30__composite_node_start_end_tags_do_not_match():
890
input_sdoc = """\
891
[DOCUMENT]892
TITLE: Test Doc893
894
[[REQUIREMENT]]895
UID: TITLE896
897
[[/FOOBAR]]898
""".lstrip()
899
900
reader = SDReader()
901
902
with pytest.raises(Exception) as exc_info:
903
_ = reader.read(input_sdoc)
904
905
assert exc_info.type is StrictDocException
906
assert exc_info.value.args[0] == (
907
"[[NODE]] syntax error: "908
"Opening and closing tags must match: "909
"opening: REQUIREMENT, closing: FOOBAR."910
)911
912
913
def test_edge_case_01_minimal_requirement(default_project_config):
914
input_sdoc = """
915
[DOCUMENT]916
TITLE: Test Doc917
918
[REQUIREMENT]919
STATEMENT: ...920
""".lstrip()
921
922
reader = SDReader()
923
924
document: SDocDocument = reader.read(input_sdoc)
925
assert isinstance(document, SDocDocument)
926
927
requirement: SDocNode = document.section_contents[0]
928
assert requirement.reserved_uid is None
929
assert requirement.reserved_title is None
930
assert requirement.reserved_statement == "..."
931
932
writer = SDWriter(default_project_config)
933
output = writer.write(document)
934
935
assert input_sdoc == output
936
937
938
def test_edge_case_02_uid_present_but_empty_with_no_space_character():
939
# Note: There is no whitespace character after "UID:".940
input_sdoc = """
941
[DOCUMENT]942
TITLE: Test Doc943
944
[REQUIREMENT]945
UID:946
""".lstrip()
947
948
reader = SDReader()
949
950
with pytest.raises(Exception) as exc_info:
951
_ = reader.read(input_sdoc)
952
953
assert exc_info.type is StrictDocException
954
assert "Expected ': '" in exc_info.value.args[0]
955
956
957
def test_edge_case_03_uid_present_but_empty_with_space_character():
958
# Note: There is a whitespace character after "UID:".959
input_sdoc = """
960
[DOCUMENT]961
TITLE: Test Doc962
963
[REQUIREMENT]964
UID: 965
""".lstrip() # noqa: W291
966
967
reader = SDReader()
968
969
with pytest.raises(Exception) as exc_info:
970
_ = reader.read(input_sdoc)
971
972
assert exc_info.type is StrictDocException
973
assert "Expected '([\\w]+[\\w()\\-\\/.: ]*)'" in exc_info.value.args[0]
974
975
976
def test_edge_case_04_uid_present_but_empty_with_two_space_characters():
977
# Note: There are two whitespace characters after "UID:".978
input_sdoc = """
979
[DOCUMENT]980
TITLE: Test Doc981
982
[REQUIREMENT]983
UID: 984
""".lstrip() # noqa: W291
985
986
reader = SDReader()
987
988
with pytest.raises(Exception) as exc_info:
989
_ = reader.read(input_sdoc)
990
991
assert exc_info.type is StrictDocException
992
assert "Expected '([\\w]+[\\w()\\-\\/.: ]*)'" in exc_info.value.args[0]
993
994
995
def test_edge_case_10_empty_multiline_field():
996
input_sdoc = """
997
[DOCUMENT]998
TITLE: Test Doc999
1000
[REQUIREMENT]1001
COMMENT: >>>1002
<<<1003
""".lstrip()
1004
1005
reader = SDReader()
1006
1007
with pytest.raises(Exception) as exc_info:
1008
_ = reader.read(input_sdoc)
1009
1010
assert exc_info.type is StrictDocException
1011
assert (
1012
"Expected '^\\[ANCHOR: ' or '[LINK: ' or "
1013
"'(?ms)(?!^<<<)(?!\\[LINK: "
1014
"([\\w]+[\\w()\\-\\/.: ]*))(?!^\\[ANCHOR: "
1015
"([\\w]+[\\w()\\-\\/.: ]*)).'" in exc_info.value.args[0]
1016
)1017
1018
1019
def test_edge_case_11_empty_multiline_field_with_one_newline():
1020
input_sdoc = """
1021
[DOCUMENT]1022
TITLE: Test Doc1023
1024
[REQUIREMENT]1025
COMMENT: >>>1026
1027
<<<1028
""".lstrip()
1029
1030
reader = SDReader()
1031
1032
with pytest.raises(Exception) as exc_info:
1033
_ = reader.read(input_sdoc)
1034
1035
assert exc_info.type is StrictDocException
1036
assert "Node statement cannot be empty." in exc_info.value.args[0]
1037
1038
1039
def test_edge_case_19_empty_section_title():
1040
input_sdoc = """
1041
[DOCUMENT]1042
TITLE: Test Doc1043
1044
[[SECTION]]1045
TITLE:1046
1047
[[/SECTION]]1048
""".lstrip()
1049
1050
reader = SDReader()
1051
1052
with pytest.raises(StrictDocException) as exc_info:
1053
_ = reader.read(input_sdoc)
1054
1055
assert exc_info.type is StrictDocException
1056
assert "TITLE:*" in exc_info.value.args[0]
1057
assert "Expected ' '" in exc_info.value.args[0]
1058
1059
1060
def test_edge_case_20_empty_section_title():
1061
input_sdoc = """
1062
[DOCUMENT]1063
TITLE: Test Doc1064
1065
[[SECTION]]1066
TITLE: 1067
1068
[[/SECTION]]1069
""".lstrip() # noqa: W291
1070
1071
reader = SDReader()
1072
1073
with pytest.raises(Exception) as exc_info:
1074
_ = reader.read(input_sdoc)
1075
1076
assert exc_info.type is StrictDocException
1077
assert "TITLE: *" in exc_info.value.args[0]
1078
1079
1080
def test_edge_case_21_section_title_with_empty_space():
1081
# Empty space after TITLE:1082
input_sdoc = """
1083
[DOCUMENT]1084
TITLE: Test Doc1085
1086
[[SECTION]]1087
TITLE: 1088
1089
[[/SECTION]]1090
""".lstrip() # noqa: W291
1091
1092
reader = SDReader()
1093
1094
with pytest.raises(Exception) as exc_info:
1095
_ = reader.read(input_sdoc)
1096
1097
assert exc_info.type is StrictDocException
1098
assert "TITLE: *" in exc_info.value.args[0]
1099
1100
1101
def test_edge_case_22_section_title_with_two_empty_spaces():
1102
# Two empty spaces after TITLE:1103
input_sdoc = """
1104
[DOCUMENT]1105
TITLE: Test Doc1106
1107
[[SECTION]]1108
TITLE: 1109
1110
[[/SECTION]]1111
""".lstrip() # noqa: W291
1112
1113
reader = SDReader()
1114
1115
with pytest.raises(Exception) as exc_info:
1116
_ = reader.read(input_sdoc)
1117
1118
assert exc_info.type is StrictDocException
1119
assert "TITLE: *" in exc_info.value.args[0]
1120
1121
1122
def test_edge_case_23_leading_spaces_do_not_imply_empy_field(
1123
default_project_config,
1124
):1125
input_sdoc = """
1126
[DOCUMENT]1127
TITLE: Test Doc1128
1129
[GRAMMAR]1130
ELEMENTS:1131
- TAG: TEXT1132
FIELDS:1133
- TITLE: STATEMENT1134
TYPE: String1135
REQUIRED: True1136
- TAG: REQUIREMENT1137
FIELDS:1138
- TITLE: STATEMENT1139
TYPE: String1140
REQUIRED: False1141
- TITLE: MY_FIELD1142
TYPE: String1143
REQUIRED: True1144
RELATIONS:1145
- TYPE: Parent1146
1147
[REQUIREMENT]1148
MY_FIELD: >>>1149
Some text here...1150
Some text here...1151
Some text here...1152
<<<1153
""".lstrip()
1154
1155
expected_sdoc = """
1156
[DOCUMENT]1157
TITLE: Test Doc1158
1159
[GRAMMAR]1160
ELEMENTS:1161
- TAG: TEXT1162
FIELDS:1163
- TITLE: STATEMENT1164
TYPE: String1165
REQUIRED: True1166
- TAG: REQUIREMENT1167
FIELDS:1168
- TITLE: STATEMENT1169
TYPE: String1170
REQUIRED: False1171
- TITLE: MY_FIELD1172
TYPE: String1173
REQUIRED: True1174
RELATIONS:1175
- TYPE: Parent1176
1177
[REQUIREMENT]1178
MY_FIELD: >>>1179
Some text here...1180
Some text here...1181
Some text here...1182
<<<1183
""".lstrip()
1184
1185
reader = SDReader()
1186
1187
document = reader.read(input_sdoc)
1188
assert isinstance(document, SDocDocument)
1189
1190
writer = SDWriter(default_project_config)
1191
output = writer.write(document)
1192
assert expected_sdoc == output
1193
1194
1195
def test_edge_case_30_single_vs_multiline_disallow_multiline_reserved_single():
1196
input_sdoc = """\
1197
[DOCUMENT]1198
TITLE: Test Doc1199
1200
[REQUIREMENT]1201
STATUS: >>>1202
Multiline status is not allowed.1203
<<<1204
""".lstrip() # noqa: W291
1205
1206
reader = SDReader()
1207
1208
with pytest.raises(Exception) as exc_info:
1209
_ = reader.read(input_sdoc)
1210
1211
assert exc_info.type is StrictDocException
1212
assert exc_info.value.args[0] == (
1213
"The node field STATUS is a reserved field and can only be written as "1214
"a single-line, not multiline, field."1215
)