diff --git a/strictdoc/core/traceability_index.py b/strictdoc/core/traceability_index.py index ec26434df..c8665d44a 100644 --- a/strictdoc/core/traceability_index.py +++ b/strictdoc/core/traceability_index.py @@ -31,6 +31,7 @@ SingleValidationError, ) from strictdoc.core.tree_cycle_detector import TreeCycleDetector +from strictdoc.core.validation_index import ValidationIndex from strictdoc.helpers.cast import assert_cast, assert_optional_cast from strictdoc.helpers.file_modification_time import set_file_modification_time from strictdoc.helpers.mid import MID @@ -54,7 +55,7 @@ def __init__( self._file_traceability_index: FileTraceabilityIndex = ( file_traceability_index ) - + self.validation_index: ValidationIndex = ValidationIndex() self.graph_database: GraphDatabase = graph_database self.document_tree: DocumentTree = document_tree self.asset_manager: Optional[AssetManager] = None diff --git a/strictdoc/core/validation_index.py b/strictdoc/core/validation_index.py new file mode 100644 index 000000000..27007e379 --- /dev/null +++ b/strictdoc/core/validation_index.py @@ -0,0 +1,50 @@ +from typing import Dict, List, Optional, Union + +from strictdoc.backend.sdoc.models.model import ( + SDocDocumentIF, + SDocNodeIF, +) + + +class ValidationIndex: + def __init__(self) -> None: + self.node_issues: Dict[ + Union[SDocNodeIF, SDocDocumentIF], Dict[Optional[str], List[str]] + ] = {} + + def add_issue( + self, + node: Union[SDocNodeIF, SDocDocumentIF], + issue: str, + field: Optional[str] = None, + subject: Optional[str] = None, + ) -> None: + self.node_issues.setdefault(node, {}).setdefault(field, []).append( + issue + ) + + if isinstance(node, SDocNodeIF): + document_node = node.get_parent_or_including_document() + self.node_issues.setdefault(document_node, {}).setdefault( + None, [] + ).append(issue) + + print_issue = issue + if subject is not None: + print_issue = f"{issue} {subject}" + print(f"warning: {print_issue}") # noqa: T201 + + def get_issues( + self, + node: Union[SDocNodeIF, SDocDocumentIF], + field: Optional[str] = None, + ) -> Optional[List[str]]: + if node not in self.node_issues: + return None + node_issues = self.node_issues[node] + if field not in node_issues: + return None + issues = node_issues[field] + if isinstance(node, SDocDocumentIF) and not node.document_is_included(): + return [f"Document has {len(issues)} issues."] + return issues diff --git a/strictdoc/export/html/_static/element.css b/strictdoc/export/html/_static/element.css index fc5c6af86..ca00643b7 100644 --- a/strictdoc/export/html/_static/element.css +++ b/strictdoc/export/html/_static/element.css @@ -1625,7 +1625,7 @@ sdoc-tabs.in_aside_panel sdoc-tab[active] { grid-column: 1 / -1; position: relative; color: var(--color-danger); - padding: var(--base-rhythm); + padding: var(--base-rhythm) 0; font-size: var(--font-size-sm); line-height: 1.5; } @@ -1634,10 +1634,10 @@ sdoc-tabs.in_aside_panel sdoc-tab[active] { position: relative; padding: calc(.5 * var(--base-rhythm)) var(--base-rhythm); border-radius: calc(.5 * var(--base-rhythm)); - border: 2px solid; + border: 1px solid; } -.field_issue-ribbon::before { +sdoc-node-content .field_issue-ribbon::before { position: absolute; content: ''; bottom: 100%; @@ -1653,6 +1653,7 @@ sdoc-tabs.in_aside_panel sdoc-tab[active] { content: ''; position: absolute; inset: 0; + pointer-events: none; } /* diff --git a/strictdoc/export/html/generators/document.py b/strictdoc/export/html/generators/document.py index f830097c0..2ab208788 100644 --- a/strictdoc/export/html/generators/document.py +++ b/strictdoc/export/html/generators/document.py @@ -36,7 +36,8 @@ def export( project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=html_templates.jinja_environment(), git_client=git_client, standalone=standalone, ) - return view_object.render_screen(html_templates.jinja_environment()) + return view_object.render_screen() diff --git a/strictdoc/export/html/generators/document_deep_trace.py b/strictdoc/export/html/generators/document_deep_trace.py index b946fc903..0f4436aab 100644 --- a/strictdoc/export/html/generators/document_deep_trace.py +++ b/strictdoc/export/html/generators/document_deep_trace.py @@ -35,7 +35,8 @@ def export_deep( project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=html_templates.jinja_environment(), git_client=git_client, standalone=False, ) - return view_object.render_screen(html_templates.jinja_environment()) + return view_object.render_screen() diff --git a/strictdoc/export/html/generators/document_pdf.py b/strictdoc/export/html/generators/document_pdf.py index 8859984ce..a3b1b689c 100644 --- a/strictdoc/export/html/generators/document_pdf.py +++ b/strictdoc/export/html/generators/document_pdf.py @@ -36,7 +36,8 @@ def export( project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=html_templates.jinja_environment(), git_client=git_client, standalone=standalone, ) - return view_object.render_screen(html_templates.jinja_environment()) + return view_object.render_screen() diff --git a/strictdoc/export/html/generators/document_table.py b/strictdoc/export/html/generators/document_table.py index 814e5b109..0f5c0bf13 100644 --- a/strictdoc/export/html/generators/document_table.py +++ b/strictdoc/export/html/generators/document_table.py @@ -35,7 +35,8 @@ def export( project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=html_templates.jinja_environment(), git_client=git_client, standalone=False, ) - return view_object.render_screen(html_templates.jinja_environment()) + return view_object.render_screen() diff --git a/strictdoc/export/html/generators/document_trace.py b/strictdoc/export/html/generators/document_trace.py index 7a01e8e1f..94c86daa9 100644 --- a/strictdoc/export/html/generators/document_trace.py +++ b/strictdoc/export/html/generators/document_trace.py @@ -35,7 +35,8 @@ def export( project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=html_templates.jinja_environment(), git_client=git_client, standalone=False, ) - return view_object.render_screen(html_templates.jinja_environment()) + return view_object.render_screen() diff --git a/strictdoc/export/html/generators/view_objects/document_screen_view_object.py b/strictdoc/export/html/generators/view_objects/document_screen_view_object.py index 740aad597..24a750227 100644 --- a/strictdoc/export/html/generators/view_objects/document_screen_view_object.py +++ b/strictdoc/export/html/generators/view_objects/document_screen_view_object.py @@ -14,7 +14,11 @@ from strictdoc.backend.sdoc.models.document import SDocDocument from strictdoc.backend.sdoc.models.document_view import ViewElement from strictdoc.backend.sdoc.models.grammar_element import GrammarElement -from strictdoc.backend.sdoc.models.model import SDocElementIF +from strictdoc.backend.sdoc.models.model import ( + SDocDocumentIF, + SDocElementIF, + SDocNodeIF, +) from strictdoc.backend.sdoc.models.node import SDocNode, SDocNodeField from strictdoc.core.document_iterator import DocumentIterationContext from strictdoc.core.document_tree import DocumentTree @@ -48,6 +52,7 @@ def __init__( project_config: ProjectConfig, link_renderer: LinkRenderer, markup_renderer: MarkupRenderer, + jinja_environment: JinjaEnvironment, git_client: GitClient, standalone: bool, ): @@ -58,6 +63,7 @@ def __init__( self.project_config: ProjectConfig = project_config self.link_renderer: LinkRenderer = link_renderer self.markup_renderer: MarkupRenderer = markup_renderer + self.jinja_environment: JinjaEnvironment = jinja_environment self.git_client: GitClient = git_client self.standalone: bool = standalone self.document_iterator = self.traceability_index.get_document_iterator( @@ -82,39 +88,37 @@ def __init__( def has_included_document(self) -> bool: return len(self.document.included_documents) > 0 - def render_screen(self, jinja_environment: JinjaEnvironment) -> Markup: + def render_screen(self) -> Markup: if self.document_type.is_document(): if self.document.config.layout == "Website": - return jinja_environment.render_template_as_markup( + return self.jinja_environment.render_template_as_markup( "website/document/index.jinja", view_object=self ) - return jinja_environment.render_template_as_markup( + return self.jinja_environment.render_template_as_markup( "screens/document/document/index.jinja", view_object=self ) elif self.document_type.is_table(): - return jinja_environment.render_template_as_markup( + return self.jinja_environment.render_template_as_markup( "screens/document/table/index.jinja", view_object=self ) elif self.document_type.is_trace(): - return jinja_environment.render_template_as_markup( + return self.jinja_environment.render_template_as_markup( "screens/document/traceability/index.jinja", view_object=self ) elif self.document_type.is_deeptrace(): - return jinja_environment.render_template_as_markup( + return self.jinja_environment.render_template_as_markup( "screens/document/traceability_deep/index.jinja", view_object=self, ) elif self.document_type.is_pdf(): - return jinja_environment.render_template_as_markup( + return self.jinja_environment.render_template_as_markup( "screens/document/pdf/index.jinja", view_object=self ) else: raise NotImplementedError(self.document_type) # pragma: no cover - def render_updated_screen( - self, jinja_environment: JinjaEnvironment - ) -> Markup: - output = jinja_environment.render_template_as_markup( + def render_updated_screen(self) -> Markup: + output = self.jinja_environment.render_template_as_markup( "actions/" "document/" "create_requirement/" @@ -122,7 +126,7 @@ def render_updated_screen( view_object=self, ) - output += jinja_environment.render_template_as_markup( + output += self.jinja_environment.render_template_as_markup( "actions/document/_shared/stream_updated_toc.jinja.html", view_object=self, ) @@ -132,7 +136,6 @@ def render_updated_screen( def render_updated_nodes_and_toc( self, nodes: Sequence[Union[SDocDocument, SDocNode]], - jinja_environment: JinjaEnvironment, ) -> str: output: str = "" @@ -147,7 +150,7 @@ def render_updated_nodes_and_toc( template_folder = "node_content" else: raise NotImplementedError - content = jinja_environment.render_template_as_markup( + content = self.jinja_environment.render_template_as_markup( f"components/{template_folder}/index_extends_node.jinja", view_object=self, node=node_, @@ -158,7 +161,7 @@ def render_updated_nodes_and_toc( target=f"article-{node_.reserved_mid}", ) - toc_content = jinja_environment.render_template_as_markup( + toc_content = self.jinja_environment.render_template_as_markup( "screens/document/_shared/toc.jinja", view_object=self ) output += render_turbo_stream( @@ -170,9 +173,9 @@ def render_updated_nodes_and_toc( return output def render_update_document_content_with_moved_node( - self, jinja_environment: JinjaEnvironment, moved_node: Any + self, moved_node: Any ) -> Markup: - content = jinja_environment.render_template_as_markup( + content = self.jinja_environment.render_template_as_markup( "screens/document/document/frame_document_content.jinja.html", view_object=self, ) @@ -181,7 +184,7 @@ def render_update_document_content_with_moved_node( action="replace", target="frame_document_content", ) - toc_content = jinja_environment.render_template_as_markup( + toc_content = self.jinja_environment.render_template_as_markup( "actions/document/_shared/stream_updated_toc.jinja.html", view_object=self, last_moved_node_id=moved_node.reserved_mid, @@ -294,6 +297,26 @@ def render_node_field(self, node_field: SDocNodeField) -> Markup: self.document_type, node_field ) + def render_issues( + self, + node: Union[SDocNodeIF, SDocDocumentIF], + field: Optional[str] = None, + ) -> str: + issues = self.traceability_index.validation_index.get_issues( + node, field=field + ) + if issues is None: + return "" + issues_html = "" + for issue_ in issues: + issue_html = self.jinja_environment.render_template_as_markup( + "components/issue/index.jinja", + issue=issue_, + view_object=self, + ) + issues_html += issue_html + return issues_html + def get_page_title(self) -> str: return self.document_type.get_page_title() diff --git a/strictdoc/export/html/generators/view_objects/search_screen_view_object.py b/strictdoc/export/html/generators/view_objects/search_screen_view_object.py index 2b5645977..b47fb9780 100644 --- a/strictdoc/export/html/generators/view_objects/search_screen_view_object.py +++ b/strictdoc/export/html/generators/view_objects/search_screen_view_object.py @@ -11,7 +11,11 @@ from strictdoc.backend.sdoc.models.anchor import Anchor from strictdoc.backend.sdoc.models.document import SDocDocument from strictdoc.backend.sdoc.models.document_view import DocumentView -from strictdoc.backend.sdoc.models.model import SDocExtendedElementIF +from strictdoc.backend.sdoc.models.model import ( + SDocDocumentIF, + SDocExtendedElementIF, + SDocNodeIF, +) from strictdoc.backend.sdoc.models.node import SDocNode from strictdoc.core.document_tree import DocumentTree from strictdoc.core.document_tree_iterator import DocumentTreeIterator @@ -118,3 +122,13 @@ def render_local_anchor( self, node: Union[Anchor, SDocNode, SDocDocument] ) -> str: return self.link_renderer.render_local_anchor(node) + + def render_issues( + self, + node: Union[SDocNodeIF, SDocDocumentIF], # noqa: ARG002 + field: Optional[str] = None, # noqa: ARG002 + ) -> str: + """ + FIXME: It is not great that this method is called from here. + """ + return "" diff --git a/strictdoc/export/html/generators/view_objects/source_file_view_object.py b/strictdoc/export/html/generators/view_objects/source_file_view_object.py index 5fde7b24f..3ab9d7c01 100644 --- a/strictdoc/export/html/generators/view_objects/source_file_view_object.py +++ b/strictdoc/export/html/generators/view_objects/source_file_view_object.py @@ -11,6 +11,7 @@ from strictdoc.backend.sdoc.models.anchor import Anchor from strictdoc.backend.sdoc.models.document import SDocDocument from strictdoc.backend.sdoc.models.document_view import NullViewElement +from strictdoc.backend.sdoc.models.model import SDocDocumentIF, SDocNodeIF from strictdoc.backend.sdoc.models.node import SDocNode, SDocNodeField from strictdoc.backend.sdoc_source_code.models.function_range_marker import ( FunctionRangeMarker, @@ -182,6 +183,16 @@ def render_local_anchor( ) -> str: return self.link_renderer.render_local_anchor(node) + def render_issues( + self, + node: Union[SDocNodeIF, SDocDocumentIF], # noqa: ARG002 + field: Optional[str] = None, # noqa: ARG002 + ) -> str: + """ + FIXME: It is not great that this method is called from here. + """ + return "" + def get_source_file_path(self) -> str: return self.source_file.in_doctree_source_file_rel_path_posix diff --git a/strictdoc/export/html/templates/components/issue/index.jinja b/strictdoc/export/html/templates/components/issue/index.jinja index 57e3bc472..4f22afeb0 100644 --- a/strictdoc/export/html/templates/components/issue/index.jinja +++ b/strictdoc/export/html/templates/components/issue/index.jinja @@ -1,12 +1,5 @@ -{# For use: insert after field #} -{# - {% with issue_field_name = 'field_name' %} - {% include "components/issue/index.jinja" %} - {% endwith %} -#} -
- Warning: '{{ issue_field_name }}' field has issue: description in details + {{ issue }}
diff --git a/strictdoc/export/html/templates/components/node_content/index.jinja b/strictdoc/export/html/templates/components/node_content/index.jinja index 7f225b2d6..c32287931 100644 --- a/strictdoc/export/html/templates/components/node_content/index.jinja +++ b/strictdoc/export/html/templates/components/node_content/index.jinja @@ -37,6 +37,8 @@ {% set _narrative_has_multiline_fields = _has_multiline_fields and user_requirement_style == 'narrative' %} {% set _narrative_has_no_multiline_fields = not _has_multiline_fields and user_requirement_style == 'narrative' %} +{{ view_object.render_issues(node) }} + diff --git a/strictdoc/export/html/templates/components/node_field/comments/index.jinja b/strictdoc/export/html/templates/components/node_field/comments/index.jinja index 865c67e68..57bd7e5cc 100644 --- a/strictdoc/export/html/templates/components/node_field/comments/index.jinja +++ b/strictdoc/export/html/templates/components/node_field/comments/index.jinja @@ -12,4 +12,5 @@ {%- endwith -%} {%- endfor %} + {{ view_object.render_issues(sdoc_entity, field="COMMENT") }} {%- endif %} diff --git a/strictdoc/export/html/templates/components/node_field/document_meta/index.jinja b/strictdoc/export/html/templates/components/node_field/document_meta/index.jinja index c267c28a7..a816e3724 100644 --- a/strictdoc/export/html/templates/components/node_field/document_meta/index.jinja +++ b/strictdoc/export/html/templates/components/node_field/document_meta/index.jinja @@ -1,5 +1,7 @@ {%- set document_config = view_object.document.config -%} +{{ view_object.render_issues(view_object.document) }} + {%- if document_config.has_meta() or document_config.has_custom_metadata() -%} {%- if view_object.document.config.uid -%} @@ -19,12 +21,6 @@ {%- include "components/field/index.jinja" -%} {%- endwith -%} - {# FIXME: Task #1229 / Uncomment example when validation logic is implemented: #} - {# - {% with issue_field_name = 'meta' %} - {% include "components/issue/index.jinja" %} - {% endwith %} - #} {%- endif -%} {% set document_date_ = view_object.render_document_date() %} diff --git a/strictdoc/export/html/templates/components/node_field/meta/index.jinja b/strictdoc/export/html/templates/components/node_field/meta/index.jinja index 39eb106e4..beef22310 100644 --- a/strictdoc/export/html/templates/components/node_field/meta/index.jinja +++ b/strictdoc/export/html/templates/components/node_field/meta/index.jinja @@ -10,5 +10,6 @@ {%- include "components/field/index.jinja" -%} {%- endwith -%} + {{ view_object.render_issues(sdoc_entity, field=meta_field[0]) }} {% endfor %} {%- endif %} diff --git a/strictdoc/export/html/templates/components/node_field/multiline/index.jinja b/strictdoc/export/html/templates/components/node_field/multiline/index.jinja index e171b841a..1cd4df6ab 100644 --- a/strictdoc/export/html/templates/components/node_field/multiline/index.jinja +++ b/strictdoc/export/html/templates/components/node_field/multiline/index.jinja @@ -12,5 +12,6 @@ {%- include "components/field/index.jinja" -%} {%- endwith -%} + {{ view_object.render_issues(sdoc_entity, field=meta_field[0]) }} {%- endfor %} {%- endif %} diff --git a/strictdoc/export/html/templates/components/node_field/rationale/index.jinja b/strictdoc/export/html/templates/components/node_field/rationale/index.jinja index f51039831..cf67c4d03 100644 --- a/strictdoc/export/html/templates/components/node_field/rationale/index.jinja +++ b/strictdoc/export/html/templates/components/node_field/rationale/index.jinja @@ -8,4 +8,5 @@ {%- include "components/field/index.jinja" -%} {%- endwith -%} + {{ view_object.render_issues(sdoc_entity, field="RATIONALE") }} {%- endif -%} diff --git a/strictdoc/export/html/templates/components/node_field/statement/index.jinja b/strictdoc/export/html/templates/components/node_field/statement/index.jinja index 093cd417b..adb31c152 100644 --- a/strictdoc/export/html/templates/components/node_field/statement/index.jinja +++ b/strictdoc/export/html/templates/components/node_field/statement/index.jinja @@ -15,5 +15,6 @@ {%- include "components/field/index.jinja" -%} {%- endwith -%} + {{ view_object.render_issues(sdoc_entity, field="STATEMENT") }} {%- endif -%} {%- endif -%} diff --git a/strictdoc/export/html/templates/components/node_field/title/index.jinja b/strictdoc/export/html/templates/components/node_field/title/index.jinja index e6294167a..5be2ded87 100644 --- a/strictdoc/export/html/templates/components/node_field/title/index.jinja +++ b/strictdoc/export/html/templates/components/node_field/title/index.jinja @@ -42,3 +42,5 @@ {% if title_has_h_level %}{% endif %} {%- endif %} + +{{ view_object.render_issues(sdoc_entity, field="TITLE") }} diff --git a/strictdoc/server/routers/main_router.py b/strictdoc/server/routers/main_router.py index 047f7a7b4..4f54bd296 100644 --- a/strictdoc/server/routers/main_router.py +++ b/strictdoc/server/routers/main_router.py @@ -201,6 +201,7 @@ def node__show_full(reference_mid: str) -> Response: project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=env(), git_client=html_generator.git_client, standalone=False, ) @@ -514,11 +515,12 @@ async def create_requirement(request: Request) -> Response: project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=env(), git_client=html_generator.git_client, standalone=False, ) - output = view_object.render_updated_screen(env()) + output = view_object.render_updated_screen() return HTMLResponse( content=output, @@ -761,6 +763,7 @@ async def document__update_requirement(request: Request) -> Response: project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=env(), git_client=html_generator.git_client, standalone=False, ) @@ -768,7 +771,6 @@ async def document__update_requirement(request: Request) -> Response: return HTMLResponse( content=view_object.render_updated_nodes_and_toc( update_requirement_command_result.this_document_requirements_to_update, - env(), ), status_code=200, headers={ @@ -834,13 +836,12 @@ def cancel_edit_requirement(requirement_mid: str) -> Response: project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=env(), git_client=html_generator.git_client, standalone=False, ) return HTMLResponse( - content=view_object.render_updated_nodes_and_toc( - [requirement], env() - ), + content=view_object.render_updated_nodes_and_toc([requirement]), headers={ "Content-Type": "text/vnd.turbo-stream.html", }, @@ -931,6 +932,7 @@ def delete_requirement( project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=env(), git_client=html_generator.git_client, standalone=False, ) @@ -1046,12 +1048,13 @@ async def move_node(request: Request) -> Response: project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=env(), git_client=html_generator.git_client, standalone=False, ) return HTMLResponse( content=view_object.render_update_document_content_with_moved_node( - env(), moved_node + moved_node ), headers={ "Content-Type": "text/vnd.turbo-stream.html", @@ -1481,6 +1484,7 @@ async def document__save_edit_config(request: Request) -> Response: project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=env(), git_client=html_generator.git_client, standalone=False, ) @@ -1567,13 +1571,12 @@ async def document__save_included_document(request: Request) -> Response: project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=env(), git_client=html_generator.git_client, standalone=False, ) return HTMLResponse( - content=view_object.render_updated_nodes_and_toc( - nodes=[document], jinja_environment=env() - ), + content=view_object.render_updated_nodes_and_toc(nodes=[document]), status_code=200, headers={ "Content-Type": "text/vnd.turbo-stream.html", @@ -1609,6 +1612,7 @@ def document__cancel_edit_config(document_mid: str) -> Response: project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=env(), git_client=html_generator.git_client, standalone=False, ) @@ -1656,6 +1660,7 @@ def document__cancel_edit_included_document(document_mid: str) -> Response: project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=env(), git_client=html_generator.git_client, standalone=False, ) @@ -1763,6 +1768,7 @@ async def document__save_grammar(request: Request) -> Response: project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=env(), git_client=html_generator.git_client, standalone=False, ) @@ -1907,6 +1913,7 @@ async def document__save_grammar_element(request: Request) -> Response: project_config=project_config, link_renderer=link_renderer, markup_renderer=markup_renderer, + jinja_environment=env(), git_client=html_generator.git_client, standalone=False, ) diff --git a/tests/integration/features/plugin/01_traceability_index_build_finished/input.sdoc b/tests/integration/features/plugin/01_traceability_index_build_finished/input.sdoc index a0706457d..a1d45911b 100644 --- a/tests/integration/features/plugin/01_traceability_index_build_finished/input.sdoc +++ b/tests/integration/features/plugin/01_traceability_index_build_finished/input.sdoc @@ -1,8 +1,78 @@ [DOCUMENT] TITLE: Hello world doc +[GRAMMAR] +ELEMENTS: +- TAG: SECTION + PROPERTIES: + IS_COMPOSITE: True + FIELDS: + - TITLE: MID + TYPE: String + REQUIRED: True + - TITLE: UID + TYPE: String + REQUIRED: False + - TITLE: PREFIX + TYPE: String + REQUIRED: False + - TITLE: TITLE + TYPE: String + REQUIRED: True +- TAG: TEXT + FIELDS: + - TITLE: MID + TYPE: String + REQUIRED: True + - TITLE: UID + TYPE: String + REQUIRED: False + - TITLE: STATEMENT + TYPE: String + REQUIRED: False +- TAG: REQUIREMENT + FIELDS: + - TITLE: MID + TYPE: String + REQUIRED: False + - TITLE: UID + TYPE: String + REQUIRED: False + - TITLE: CUSTOM_META_FIELD + TYPE: String + REQUIRED: False + - TITLE: STATUS + TYPE: String + REQUIRED: False + - TITLE: TITLE + TYPE: String + REQUIRED: False + - TITLE: STATEMENT + TYPE: String + REQUIRED: False + - TITLE: RATIONALE + TYPE: String + REQUIRED: False + - TITLE: COMMENT + TYPE: String + REQUIRED: False + - TITLE: CUSTOM_CONTENT_FIELD + TYPE: String + REQUIRED: False + [REQUIREMENT] -TITLE: I am a title with a dot at the end, I will trigger the validation. +UID: REQ-1 +CUSTOM_META_FIELD: Custom meta content. +TITLE: System A -> B behavior STATEMENT: >>> System A shall do B. <<< +RATIONALE: >>> +Nobody knows anymore why System A shall do B. +<<< +COMMENT: >>> +This is a comment about system A. +<<< +CUSTOM_CONTENT_FIELD: >>> +This is a custom field. +<<< diff --git a/tests/integration/features/plugin/01_traceability_index_build_finished/test.itest b/tests/integration/features/plugin/01_traceability_index_build_finished/test.itest index cc9a995b4..49b8019f7 100644 --- a/tests/integration/features/plugin/01_traceability_index_build_finished/test.itest +++ b/tests/integration/features/plugin/01_traceability_index_build_finished/test.itest @@ -1,8 +1,26 @@ RUN: %strictdoc export %S --output-dir %T | filecheck %s --dump-input=fail CHECK: warning: traceability_index_build_finished() is called. -CHECK: warning: Node title ends with a dot: "I am a title with a dot at the end, I will trigger the validation.". +CHECK: warning: The whole node is really bad. Node: System A -> B behavior +CHECK: warning: UID field is really bad. Node: System A -> B behavior +CHECK: warning: CUSTOM_META_FIELD field is really bad. Node: System A -> B behavior +CHECK: warning: TITLE field is really bad. Node: System A -> B behavior +CHECK: warning: STATEMENT field is really bad. Node: System A -> B behavior +CHECK: warning: RATIONALE field is really bad. Node: System A -> B behavior +CHECK: warning: COMMENT field is really bad. Node: System A -> B behavior +CHECK: warning: CUSTOM_CONTENT_FIELD field is really bad. Node: System A -> B behavior CHECK: Published: Hello world doc -RUN: %cat %T/html/index.html | filecheck %s --dump-input=fail --check-prefix CHECK-HTML -CHECK-HTML: Hello world doc -CHECK-HTML: input.sdoc +RUN: %cat %T/html/index.html | filecheck %s --dump-input=fail --check-prefix CHECK-INDEX +CHECK-INDEX: Hello world doc +CHECK-INDEX: input.sdoc + +RUN: %cat %T/html/%THIS_TEST_FOLDER/input.html | filecheck %s --dump-input=fail --check-prefix CHECK-HTML +CHECK-HTML: Document has 8 issues. +CHECK-HTML: The whole node is really bad. +CHECK-HTML: TITLE field is really bad. +CHECK-HTML: UID field is really bad. +CHECK-HTML: CUSTOM_META_FIELD field is really bad. +CHECK-HTML: STATEMENT field is really bad. +CHECK-HTML: RATIONALE field is really bad. +CHECK-HTML: COMMENT field is really bad. +CHECK-HTML: CUSTOM_CONTENT_FIELD field is really bad. diff --git a/tests/integration/features/plugin/01_traceability_index_build_finished/user_plugin.py b/tests/integration/features/plugin/01_traceability_index_build_finished/user_plugin.py index b2a49791f..85a476c5e 100644 --- a/tests/integration/features/plugin/01_traceability_index_build_finished/user_plugin.py +++ b/tests/integration/features/plugin/01_traceability_index_build_finished/user_plugin.py @@ -19,5 +19,51 @@ def traceability_index_build_finished(self, traceability: TraceabilityIndex): if not isinstance(node, SDocNode): continue - if node.reserved_title.endswith("."): - print(f'warning: Node title ends with a dot: "{node.reserved_title}".') # noqa: T201 + traceability.validation_index.add_issue( + node, + issue="The whole node is really bad.", + field=None, + subject=f"Node: {node.reserved_title}", + ) + traceability.validation_index.add_issue( + node, + issue="UID field is really bad.", + field="UID", + subject=f"Node: {node.reserved_title}", + ) + traceability.validation_index.add_issue( + node, + issue="CUSTOM_META_FIELD field is really bad.", + field="CUSTOM_META_FIELD", + subject=f"Node: {node.reserved_title}", + ) + traceability.validation_index.add_issue( + node, + issue="TITLE field is really bad.", + field="TITLE", + subject=f"Node: {node.reserved_title}", + ) + traceability.validation_index.add_issue( + node, + issue="STATEMENT field is really bad.", + field="STATEMENT", + subject=f"Node: {node.reserved_title}", + ) + traceability.validation_index.add_issue( + node, + issue="RATIONALE field is really bad.", + field="RATIONALE", + subject=f"Node: {node.reserved_title}", + ) + traceability.validation_index.add_issue( + node, + issue="COMMENT field is really bad.", + field="COMMENT", + subject=f"Node: {node.reserved_title}", + ) + traceability.validation_index.add_issue( + node, + issue="CUSTOM_CONTENT_FIELD field is really bad.", + field="CUSTOM_CONTENT_FIELD", + subject=f"Node: {node.reserved_title}", + )