Path:
strictdoc/export/html/generators/source_file_coverage.py
Lines:
149
Non-empty lines:
131
Non-empty lines covered with requirements:
131 / 131 (100.0%)
Functions:
15
Functions covered by requirements:
15 / 15 (100.0%)
- "6.10.1. Project source code coverage" (REQUIREMENT)
- "6.10.1. Project source code coverage" (REQUIREMENT)
1
"""2
@relation(SDOC-SRS-35, scope=file)3
"""4
5
from typing import Optional
6
7
from markupsafe import Markup
8
9
from strictdoc import __version__
10
from strictdoc.backend.sdoc_source_code.models.source_file_info import (
11
SourceFileTraceabilityInfo,
12
)13
from strictdoc.core.file_system.source_tree import SourceFile
14
from strictdoc.core.project_config import ProjectConfig
15
from strictdoc.core.traceability_index import TraceabilityIndex
16
from strictdoc.export.html.html_templates import HTMLTemplates, JinjaEnvironment
17
from strictdoc.export.html.renderers.link_renderer import LinkRenderer
18
19
20
class SourceCoverageViewObject:
21
def __init__(
22
self,
23
*,
24
traceability_index: TraceabilityIndex,
25
project_config: ProjectConfig,
26
) -> None:
27
self.traceability_index: TraceabilityIndex = traceability_index
28
self.project_config: ProjectConfig = project_config
29
self.link_renderer: LinkRenderer = LinkRenderer(
30
root_path="", static_path=project_config.dir_for_sdoc_assets
31
)32
self.is_running_on_server: bool = project_config.is_running_on_server
33
self.strictdoc_version = __version__
34
35
def get_document_level(self) -> int:
36
return 0
37
38
def render_screen(self, jinja_environment: JinjaEnvironment) -> Markup:
39
return jinja_environment.render_template_as_markup(
40
"screens/source_file_coverage/index.jinja", view_object=self
41
)42
43
def render_static_url(self, url: str) -> str:
44
return self.link_renderer.render_static_url(url)
45
46
def render_url(self, url: str) -> str:
47
# FIXME: Switch to Markup(...).48
return self.link_renderer.render_url(url)
49
50
def get_file_stats_lines_total(self, source_file: SourceFile) -> str:
51
trace_info: Optional[SourceFileTraceabilityInfo] = (
52
self.traceability_index.get_coverage_info_weak(
53
source_file.in_doctree_source_file_rel_path_posix
54
)55
)56
if trace_info is None:
57
return "0"
58
return str(trace_info.file_stats.lines_total)
59
60
def get_file_stats_lines_total_non_empty(
61
self, source_file: SourceFile
62
) -> str:
63
trace_info: Optional[SourceFileTraceabilityInfo] = (
64
self.traceability_index.get_coverage_info_weak(
65
source_file.in_doctree_source_file_rel_path_posix
66
)67
)68
if trace_info is None:
69
return "0"
70
return str(trace_info.file_stats.lines_non_empty)
71
72
def get_file_stats_non_empty_lines_covered(
73
self, source_file: SourceFile
74
) -> str:
75
trace_info: Optional[SourceFileTraceabilityInfo] = (
76
self.traceability_index.get_coverage_info_weak(
77
source_file.in_doctree_source_file_rel_path_posix
78
)79
)80
if trace_info is None:
81
return "0"
82
return str(trace_info.ng_lines_covered)
83
84
def get_file_stats_non_empty_lines_covered_percentage(
85
self, source_file: SourceFile
86
) -> str:
87
trace_info: Optional[SourceFileTraceabilityInfo] = (
88
self.traceability_index.get_coverage_info_weak(
89
source_file.in_doctree_source_file_rel_path_posix
90
)91
)92
if trace_info is None:
93
return f"{0:.1f}"
94
covered = trace_info.ng_lines_covered
95
total_non_empty = trace_info.file_stats.lines_non_empty
96
percentage = (
97
(covered / total_non_empty * 100) if total_non_empty > 0 else 0
98
)99
return f"{percentage:.1f}"
100
101
def get_file_stats_functions_total(self, source_file: SourceFile) -> str:
102
trace_info: Optional[SourceFileTraceabilityInfo] = (
103
self.traceability_index.get_coverage_info_weak(
104
source_file.in_doctree_source_file_rel_path_posix
105
)106
)107
if trace_info is None:
108
return "0"
109
return str(len(trace_info.functions))
110
111
def get_file_stats_functions_covered(self, source_file: SourceFile) -> str:
112
trace_info: Optional[SourceFileTraceabilityInfo] = (
113
self.traceability_index.get_coverage_info_weak(
114
source_file.in_doctree_source_file_rel_path_posix
115
)116
)117
if trace_info is None:
118
return "0"
119
return str(trace_info.covered_functions)
120
121
def get_file_stats_functions_covered_percentage(
122
self, source_file: SourceFile
123
) -> str:
124
trace_info: Optional[SourceFileTraceabilityInfo] = (
125
self.traceability_index.get_coverage_info_weak(
126
source_file.in_doctree_source_file_rel_path_posix
127
)128
)129
if trace_info is None:
130
return f"{0:.1f}"
131
covered = trace_info.covered_functions
132
total = len(trace_info.functions)
133
percentage = (covered / total * 100) if total > 0 else 0
134
return f"{percentage:.1f}"
135
136
137
class SourceFileCoverageHTMLGenerator:
138
@staticmethod139
def export(
140
*,
141
project_config: ProjectConfig,
142
traceability_index: TraceabilityIndex,
143
html_templates: HTMLTemplates,
144
) -> Markup:
145
view_object = SourceCoverageViewObject(
146
traceability_index=traceability_index,
147
project_config=project_config,
148
)149
return view_object.render_screen(html_templates.jinja_environment())