Path:
strictdoc/core/analyzers/document_uid_analyzer.py
Lines:
118
Non-empty lines:
106
Non-empty lines covered with requirements:
106 / 106 (100.0%)
Functions:
3
Functions covered by requirements:
3 / 3 (100.0%)
1
import typing
2
from collections import Counter
3
from typing import Dict, List
4
5
from strictdoc.backend.sdoc.models.document import SDocDocument
6
from strictdoc.backend.sdoc.models.node import SDocNode
7
from strictdoc.core.analyzers.document_stats import (
8
DocumentStats,
9
DocumentTreeStats,
10
SinglePrefixRequirements,
11
)12
from strictdoc.core.document_iterator import SDocDocumentIterator
13
from strictdoc.core.document_tree import DocumentTree
14
from strictdoc.core.traceability_index import TraceabilityIndex
15
from strictdoc.helpers.cast import assert_cast
16
from strictdoc.helpers.string import (
17
extract_last_numeric_part,
18
extract_numeric_uid_prefix_part,
19
)20
21
22
class DocumentUIDAnalyzer:
23
@staticmethod24
def analyze_document_tree(
25
traceability_index: TraceabilityIndex,
26
) -> DocumentTreeStats:
27
global_requirements_per_prefix: Dict[str, SinglePrefixRequirements] = {}
28
document_tree_stats: List[DocumentStats] = []
29
section_uids_so_far: typing.Counter[str] = Counter()
30
31
document_tree: DocumentTree = assert_cast(
32
traceability_index.document_tree, DocumentTree
33
)34
35
for document in document_tree.document_list:
36
document_stats: DocumentStats = (
37
DocumentUIDAnalyzer.analyze_document(document)
38
)39
for (
40
requirement_prefix_,
41
prefix_requirements_,
42
) in document_stats.requirements_per_prefix.items():
43
global_prefix_requirements = (
44
global_requirements_per_prefix.setdefault(
45
requirement_prefix_, SinglePrefixRequirements()
46
)47
)48
global_prefix_requirements.requirements_no_uid.extend(
49
prefix_requirements_.requirements_no_uid
50
)51
global_prefix_requirements.requirements_uid_numbers.extend(
52
prefix_requirements_.requirements_uid_numbers
53
)54
document_tree_stats.append(document_stats)
55
for section_uid_ in document_stats.section_uids_so_far:
56
section_uids_so_far[section_uid_] += 1
57
return DocumentTreeStats(
58
single_document_stats=document_tree_stats,
59
requirements_per_prefix=global_requirements_per_prefix,
60
section_uids_so_far=section_uids_so_far,
61
)62
63
@staticmethod64
def analyze_document(
65
document: SDocDocument,
66
) -> DocumentStats:
67
this_document_stats = DocumentStats(document)
68
document_iterator = SDocDocumentIterator(document)
69
for node, _ in document_iterator.all_content():
70
if isinstance(node, SDocNode) and node.node_type == "SECTION":
71
if node.reserved_uid is not None:
72
this_document_stats.section_uids_so_far[
73
node.reserved_uid
74
] += 1
75
else:
76
this_document_stats.sections_without_uid.append(node)
77
continue78
if not isinstance(node, SDocNode):
79
continue80
if node.node_type in ("TEXT", "SECTION"):
81
continue82
requirement: SDocNode = node
83
node_prefix: typing.Optional[str] = requirement.get_prefix()
84
if node_prefix is None:
85
continue86
87
if node_prefix not in this_document_stats.requirements_per_prefix:
88
this_document_stats.requirements_per_prefix[node_prefix] = (
89
SinglePrefixRequirements()
90
)91
92
prefix_requirements: SinglePrefixRequirements = (
93
this_document_stats.requirements_per_prefix[node_prefix]
94
)95
if requirement.reserved_uid is None:
96
prefix_requirements.requirements_no_uid.append(requirement)
97
else:
98
requirement_prefix = extract_numeric_uid_prefix_part(
99
requirement.reserved_uid
100
)101
102
# If the requirement has a prefix which is different to that of103
# the parent section/document's prefix, we ignore this node as104
# incredible for contributing to the next UID calculation.105
if requirement_prefix != node_prefix:
106
continue107
108
requirement_uid_numeric_part = extract_last_numeric_part(
109
requirement.reserved_uid
110
)111
assert len(requirement_uid_numeric_part) > 0
112
requirement_uid_number = int(requirement_uid_numeric_part)
113
114
prefix_requirements.requirements_uid_numbers.append(
115
requirement_uid_number116
)117
118
return this_document_stats