diff --git a/strictdoc/core/traceability_index.py b/strictdoc/core/traceability_index.py index c5aa43661..4ec2f8591 100644 --- a/strictdoc/core/traceability_index.py +++ b/strictdoc/core/traceability_index.py @@ -354,9 +354,10 @@ def get_node_by_uid_weak2(self, uid: str): def get_linkable_node_by_uid( self, uid - ) -> Union[SDocNode, SDocSection, Anchor]: + ) -> Union[SDocDocument, SDocNode, SDocSection, Anchor]: return assert_cast( - self.get_node_by_uid(uid), (SDocNode, SDocSection, Anchor) + self.get_node_by_uid(uid), + (SDocDocument, SDocNode, SDocSection, Anchor), ) def get_node_by_uid_weak( @@ -383,16 +384,16 @@ def get_node_by_uid_weak( def get_linkable_node_by_uid_weak( self, uid - ) -> Union[SDocNode, SDocSection, Anchor, None]: + ) -> Union[SDocDocument, SDocNode, SDocSection, Anchor, None]: return assert_optional_cast( self.graph_database.get_link_value_weak( link_type=GraphLinkType.UID_TO_NODE, lhs_node=uid ), - (SDocNode, SDocSection, Anchor), + (SDocDocument, SDocNode, SDocSection, Anchor), ) def get_incoming_links( - self, node: Union[SDocNode, SDocSection, Anchor] + self, node: Union[SDocDocument, SDocNode, SDocSection, Anchor] ) -> Optional[List[InlineLink]]: incoming_links = self.graph_database.get_link_values_weak( link_type=GraphLinkType.NODE_TO_INCOMING_LINKS, @@ -448,6 +449,20 @@ def create_traceability_info( source_file_rel_path, traceability_info, traceability_index ) + def create_document(self, document: SDocDocument) -> None: + assert isinstance(document, SDocDocument) + if document.reserved_uid is not None: + self.graph_database.create_link( + link_type=GraphLinkType.UID_TO_NODE, + lhs_node=document.reserved_uid, + rhs_node=document, + ) + self.graph_database.create_link( + link_type=GraphLinkType.MID_TO_NODE, + lhs_node=document.reserved_mid, + rhs_node=document, + ) + def create_section(self, section: SDocSection) -> None: assert isinstance(section, SDocSection) if section.reserved_uid is not None: @@ -469,12 +484,14 @@ def create_inline_link(self, new_link: InlineLink): if self.graph_database.has_link( link_type=GraphLinkType.UID_TO_NODE, lhs_node=new_link.link ): - node_or_anchor: Union[SDocNode, SDocSection, Anchor] = assert_cast( + node_or_anchor: Union[ + SDocDocument, SDocNode, SDocSection, Anchor + ] = assert_cast( self.graph_database.get_link_value( link_type=GraphLinkType.UID_TO_NODE, lhs_node=new_link.link, ), - (SDocNode, SDocSection, Anchor), + (SDocDocument, SDocNode, SDocSection, Anchor), ) self.graph_database.create_link( link_type=GraphLinkType.NODE_TO_INCOMING_LINKS, @@ -767,6 +784,21 @@ def update_disconnect_two_documents_if_no_links_left( rhs_node=document.reserved_mid, ) + def delete_document(self, document: SDocDocument) -> None: + assert isinstance(document, SDocDocument), document + + self.graph_database.delete_link( + link_type=GraphLinkType.MID_TO_NODE, + lhs_node=document.reserved_mid, + rhs_node=document, + ) + if document.reserved_uid is not None: + self.graph_database.delete_link( + link_type=GraphLinkType.UID_TO_NODE, + lhs_node=document.reserved_uid, + rhs_node=document, + ) + def delete_section(self, section: SDocSection) -> None: assert isinstance(section, SDocSection), section diff --git a/strictdoc/core/traceability_index_builder.py b/strictdoc/core/traceability_index_builder.py index f5d04cb77..73994ae26 100644 --- a/strictdoc/core/traceability_index_builder.py +++ b/strictdoc/core/traceability_index_builder.py @@ -232,7 +232,9 @@ def create_from_document_tree( ), ( GraphLinkType.UID_TO_NODE, - OneToOneDictionary(str, (SDocNode, SDocSection, Anchor)), + OneToOneDictionary( + str, (SDocDocument, SDocNode, SDocSection, Anchor) + ), ), ( GraphLinkType.UID_TO_REQUIREMENT_CONNECTIONS, @@ -352,7 +354,12 @@ def create_from_document_tree( lhs_node=document.reserved_mid, rhs_node=document, ) - # FIXME: Register Document with UID_TO_NODE + if document.uid: + graph_database.create_link( + link_type=GraphLinkType.UID_TO_NODE, + lhs_node=document.uid, + rhs_node=document, + ) document_tags: Dict[str, int] = {} graph_database.create_link( diff --git a/strictdoc/core/transforms/update_document_config.py b/strictdoc/core/transforms/update_document_config.py index 59e293d4d..aae06e842 100644 --- a/strictdoc/core/transforms/update_document_config.py +++ b/strictdoc/core/transforms/update_document_config.py @@ -1,8 +1,9 @@ # mypy: disable-error-code="arg-type,no-untyped-call,no-untyped-def" from collections import defaultdict -from typing import Dict, List +from typing import Dict, List, Optional from strictdoc.backend.sdoc.models.document import SDocDocument +from strictdoc.backend.sdoc.models.inline_link import InlineLink from strictdoc.core.traceability_index import ( TraceabilityIndex, ) @@ -36,11 +37,6 @@ def perform(self): # Update the document. document.title = form_object.document_title - document.config.uid = ( - form_object.document_uid - if len(form_object.document_uid) > 0 - else None - ) document.config.version = ( form_object.document_version if len(form_object.document_version) > 0 @@ -52,6 +48,16 @@ def perform(self): else None ) + self.traceability_index.delete_document(document) + + document.config.uid = ( + form_object.document_uid + if len(form_object.document_uid) > 0 + else None + ) + + self.traceability_index.create_document(document) + def validate( self, form_object: DocumentConfigFormObject, @@ -59,9 +65,31 @@ def validate( ): errors: Dict[str, List[str]] = defaultdict(list) assert isinstance(document, SDocDocument) + if len(form_object.document_title) == 0: errors["TITLE"].append("Document title must not be empty.") + # Ensure that UID doesn't have any incoming links if it is going to be + # renamed or removed + existing_uid = document.reserved_uid + new_uid = form_object.document_uid + if existing_uid is not None: + if new_uid is None or existing_uid != new_uid: + existing_incoming_links: Optional[List[InlineLink]] = ( + self.traceability_index.get_incoming_links(document) + ) + if ( + existing_incoming_links is not None + and len(existing_incoming_links) > 0 + ): + errors["UID"].append( + ( + "Renaming a node UID when the node has " + "incoming links is not supported yet. " + "Please delete all incoming links first." + ), + ) + if len(errors): raise MultipleValidationError( "Document form has not passed validation.", errors=errors diff --git a/strictdoc/export/html/form_objects/requirement_form_object.py b/strictdoc/export/html/form_objects/requirement_form_object.py index 9be666084..10d2c122e 100644 --- a/strictdoc/export/html/form_objects/requirement_form_object.py +++ b/strictdoc/export/html/form_objects/requirement_form_object.py @@ -193,7 +193,7 @@ def __init__( context_document_mid: str, fields: List[RequirementFormField], reference_fields: List[RequirementReferenceFormField], - exiting_requirement_uid: Optional[str], + existing_requirement_uid: Optional[str], grammar: DocumentGrammar, # FIXME: Better name relation_types: List[str], @@ -213,7 +213,7 @@ def __init__( self.reference_fields: List[RequirementReferenceFormField] = ( reference_fields ) - self.exiting_requirement_uid: Optional[str] = exiting_requirement_uid + self.existing_requirement_uid: Optional[str] = existing_requirement_uid self.grammar: DocumentGrammar = grammar self.relation_types: List[str] = relation_types self.basic_free_text: bool = basic_free_text @@ -225,7 +225,7 @@ def create_from_request( requirement_mid: str, request_form_data: FormData, document: SDocDocument, - exiting_requirement_uid: Optional[str], + existing_requirement_uid: Optional[str], basic_free_text: bool, ) -> "RequirementFormObject": request_form_data_as_list = [ @@ -326,7 +326,7 @@ def create_from_request( context_document_mid=context_document_mid, fields=form_fields, reference_fields=form_ref_fields, - exiting_requirement_uid=exiting_requirement_uid, + existing_requirement_uid=existing_requirement_uid, grammar=grammar, relation_types=element.get_relation_types(), basic_free_text=basic_free_text, @@ -384,7 +384,7 @@ def create_new( context_document_mid=context_document_mid, fields=form_fields, reference_fields=[], - exiting_requirement_uid=None, + existing_requirement_uid=None, grammar=grammar, relation_types=element.get_relation_types(), basic_free_text=False, @@ -474,7 +474,7 @@ def create_from_requirement( context_document_mid=context_document_mid, fields=form_fields, reference_fields=form_refs_fields, - exiting_requirement_uid=requirement.reserved_uid, + existing_requirement_uid=requirement.reserved_uid, grammar=grammar, relation_types=grammar_element_relations, basic_free_text=requirement.basic_free_text, @@ -617,7 +617,7 @@ def validate( new_node_uid_or_none = new_node_uid if new_node_uid_or_none is not None and ( - self.is_new or self.exiting_requirement_uid != new_node_uid_or_none + self.is_new or self.existing_requirement_uid != new_node_uid_or_none ): existing_node_with_this_uid = ( traceability_index.get_node_by_uid_weak(new_node_uid_or_none) @@ -636,10 +636,10 @@ def validate( Ensure that UID doesn't have any incoming links if it is going to be renamed or removed. """ - if self.exiting_requirement_uid is not None: + if self.existing_requirement_uid is not None: if ( new_node_uid_or_none is None - or self.exiting_requirement_uid != new_node_uid_or_none + or self.existing_requirement_uid != new_node_uid_or_none ): existing_node: SDocNode = traceability_index.get_node_by_mid( MID(self.requirement_mid) @@ -725,8 +725,8 @@ def validate( ) if ( - self.exiting_requirement_uid is not None - and self.exiting_requirement_uid != requirement_uid + self.existing_requirement_uid is not None + and self.existing_requirement_uid != requirement_uid ): if len(self.reference_fields) > 0: self.add_error( @@ -738,7 +738,7 @@ def validate( ) requirement_connections: SDocNodeConnections = ( traceability_index.get_node_connections( - self.exiting_requirement_uid + self.existing_requirement_uid ) ) if len(requirement_connections.children): diff --git a/strictdoc/server/routers/main_router.py b/strictdoc/server/routers/main_router.py index 0fc917cd6..8effa00ca 100644 --- a/strictdoc/server/routers/main_router.py +++ b/strictdoc/server/routers/main_router.py @@ -870,7 +870,7 @@ async def create_requirement(request: Request): requirement_mid=requirement_mid, request_form_data=request_form_data, document=document, - exiting_requirement_uid=None, + existing_requirement_uid=None, basic_free_text=basic_free_text, ) ) @@ -1090,7 +1090,7 @@ async def document__update_requirement(request: Request): requirement_mid=requirement_mid, request_form_data=request_form_data, document=document, - exiting_requirement_uid=requirement.reserved_uid, + existing_requirement_uid=requirement.reserved_uid, basic_free_text=requirement.basic_free_text, ) ) @@ -1763,7 +1763,7 @@ def document__add_comment( context_document_mid=context_document_mid, fields=[], reference_fields=[], - exiting_requirement_uid=None, + existing_requirement_uid=None, grammar=grammar, relation_types=[], basic_free_text=False, @@ -1815,7 +1815,7 @@ def document__add_relation( context_document_mid=context_document_mid, fields=[], reference_fields=[], - exiting_requirement_uid=None, + existing_requirement_uid=None, grammar=grammar, relation_types=grammar_element_relations, basic_free_text=False, diff --git a/tests/end2end/helpers/screens/document/screen_document.py b/tests/end2end/helpers/screens/document/screen_document.py index 442d9b148..a509bab55 100644 --- a/tests/end2end/helpers/screens/document/screen_document.py +++ b/tests/end2end/helpers/screens/document/screen_document.py @@ -98,3 +98,9 @@ def do_drag_first_toc_node_to_the_second(self) -> None: raise TimeoutError( "StrictDoc custom timeout: Moving element in the TOC" ) + + def do_click_on_tree_document(self, doc_order: int = 1) -> None: + self.test_case.assert_element_not_present("//sdoc-modal", by=By.XPATH) + self.test_case.click_xpath( + f'(//*[@data-testid="tree-document-link"])[{doc_order}]' + ) diff --git a/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_create/create_document_with_uid_and_node_with_LINK/expected_output/document1.sdoc b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_create/create_document_with_uid_and_node_with_LINK/expected_output/document1.sdoc new file mode 100644 index 000000000..066064096 --- /dev/null +++ b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_create/create_document_with_uid_and_node_with_LINK/expected_output/document1.sdoc @@ -0,0 +1,9 @@ +[DOCUMENT] +TITLE: Document 1 + +[REQUIREMENT] +UID: REQ-1 +TITLE: Requirement 1 +STATEMENT: >>> +Modified. [LINK: DOC-2] +<<< diff --git a/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_create/create_document_with_uid_and_node_with_LINK/expected_output/document2.sdoc b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_create/create_document_with_uid_and_node_with_LINK/expected_output/document2.sdoc new file mode 100644 index 000000000..fdeecdd02 --- /dev/null +++ b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_create/create_document_with_uid_and_node_with_LINK/expected_output/document2.sdoc @@ -0,0 +1,3 @@ +[DOCUMENT] +TITLE: Document 2 +UID: DOC-2 diff --git a/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_create/create_document_with_uid_and_node_with_LINK/input/document1.sdoc b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_create/create_document_with_uid_and_node_with_LINK/input/document1.sdoc new file mode 100644 index 000000000..089c95f00 --- /dev/null +++ b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_create/create_document_with_uid_and_node_with_LINK/input/document1.sdoc @@ -0,0 +1,9 @@ +[DOCUMENT] +TITLE: Document 1 + +[REQUIREMENT] +UID: REQ-1 +TITLE: Requirement 1 +STATEMENT: >>> +Nothing here yet. +<<< diff --git a/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_create/create_document_with_uid_and_node_with_LINK/test_case.py b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_create/create_document_with_uid_and_node_with_LINK/test_case.py new file mode 100644 index 000000000..1d938897e --- /dev/null +++ b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_create/create_document_with_uid_and_node_with_LINK/test_case.py @@ -0,0 +1,66 @@ +from tests.end2end.e2e_case import E2ECase +from tests.end2end.end2end_test_setup import End2EndTestSetup +from tests.end2end.helpers.components.node.document_root import Form_EditConfig +from tests.end2end.helpers.screens.document.form_edit_requirement import ( + Form_EditRequirement, +) +from tests.end2end.helpers.screens.project_index.form_add_document import ( + Form_AddDocument, +) +from tests.end2end.helpers.screens.project_index.screen_project_index import ( + Screen_ProjectIndex, +) +from tests.end2end.server import SDocTestServer + + +class Test(E2ECase): + def test(self): + test_setup = End2EndTestSetup(path_to_test_file=__file__) + + # Run server. + with SDocTestServer( + input_path=test_setup.path_to_sandbox + ) as test_server: + self.open(test_server.get_host_and_port()) + + screen_project_index = Screen_ProjectIndex(self) + screen_project_index.assert_on_screen() + screen_project_index.assert_contains_document("Document 1") + + # Create Document 2 and change UID to DOC-2 + form_add_document: Form_AddDocument = ( + screen_project_index.do_open_modal_form_add_document() + ) + form_add_document.do_fill_in_title("Document 2") + form_add_document.do_fill_in_path("document2.sdoc") + form_add_document.do_form_submit() + + screen_document = screen_project_index.do_click_on_the_document(2) + screen_document.assert_on_screen_document() + screen_document.assert_header_document_title("Document 2") + + document_node = screen_document.get_root_node() + form_edit_document: Form_EditConfig = ( + document_node.do_open_form_edit_config() + ) + form_edit_document.do_fill_in_document_uid("DOC-2") + form_edit_document.do_form_submit() + + # Go to Document 1 and link requirement statement to DOC-2 + screen_document.do_click_on_tree_document(1) + screen_document.assert_header_document_title("Document 1") + + req_node_1 = screen_document.get_node(1) + req_node_edit_form: Form_EditRequirement = ( + req_node_1.do_open_form_edit_requirement() + ) + req_node_edit_form.do_fill_in_field_statement( + "Modified. [LINK: DOC-2]" + ) + req_node_edit_form.do_form_submit() + + # Click new link and verify it brings us to Document 2 + self.click_xpath("//sdoc-node//a[contains(., 'Document 2')]") + screen_document.assert_header_document_title("Document 2") + + assert test_setup.compare_sandbox_and_expected_output() diff --git a/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_update/_validations/update_node_must_prevent_renaming_or_removing_UID_when_incoming_links/expected_output/document.sdoc b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_update/_validations/update_node_must_prevent_renaming_or_removing_UID_when_incoming_links/expected_output/document.sdoc index b58dc825e..dded93345 100644 --- a/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_update/_validations/update_node_must_prevent_renaming_or_removing_UID_when_incoming_links/expected_output/document.sdoc +++ b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_update/_validations/update_node_must_prevent_renaming_or_removing_UID_when_incoming_links/expected_output/document.sdoc @@ -1,10 +1,11 @@ [DOCUMENT] TITLE: Document 1 +UID: DOC-1 [REQUIREMENT] UID: REQ-1 STATEMENT: >>> -Hello world +Hello world [LINK: DOC-1] <<< [REQUIREMENT] diff --git a/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_update/_validations/update_node_must_prevent_renaming_or_removing_UID_when_incoming_links/input/document.sdoc b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_update/_validations/update_node_must_prevent_renaming_or_removing_UID_when_incoming_links/input/document.sdoc index b58dc825e..dded93345 100644 --- a/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_update/_validations/update_node_must_prevent_renaming_or_removing_UID_when_incoming_links/input/document.sdoc +++ b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_update/_validations/update_node_must_prevent_renaming_or_removing_UID_when_incoming_links/input/document.sdoc @@ -1,10 +1,11 @@ [DOCUMENT] TITLE: Document 1 +UID: DOC-1 [REQUIREMENT] UID: REQ-1 STATEMENT: >>> -Hello world +Hello world [LINK: DOC-1] <<< [REQUIREMENT] diff --git a/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_update/_validations/update_node_must_prevent_renaming_or_removing_UID_when_incoming_links/test_case.py b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_update/_validations/update_node_must_prevent_renaming_or_removing_UID_when_incoming_links/test_case.py index 2386fca45..8c56395f0 100644 --- a/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_update/_validations/update_node_must_prevent_renaming_or_removing_UID_when_incoming_links/test_case.py +++ b/tests/end2end/screens/document/_cross_cutting/LINK_and_ANCHOR/node/_update/_validations/update_node_must_prevent_renaming_or_removing_UID_when_incoming_links/test_case.py @@ -1,5 +1,6 @@ from tests.end2end.e2e_case import E2ECase from tests.end2end.end2end_test_setup import End2EndTestSetup +from tests.end2end.helpers.components.node.document_root import Form_EditConfig from tests.end2end.helpers.screens.document.form_edit_requirement import ( Form_EditRequirement, ) @@ -28,6 +29,15 @@ def test(self): screen_document.assert_on_screen_document() screen_document.assert_header_document_title("Document 1") + document_node = screen_document.get_root_node() + form_edit_document: Form_EditConfig = ( + document_node.do_open_form_edit_config() + ) + form_edit_document.do_fill_in_document_uid("DOC-2") + form_edit_document.do_form_submit_and_catch_error( + "Renaming a node UID when the node has incoming links is not supported yet. Please delete all incoming links first." + ) + text_node_1 = screen_document.get_node(1) form_edit_requirement: Form_EditRequirement = ( text_node_1.do_open_form_edit_requirement() diff --git a/tests/integration/commands/export/html/markup/11_node_LINK_references_a_document/input1.sdoc b/tests/integration/commands/export/html/markup/11_node_LINK_references_a_document/input1.sdoc new file mode 100644 index 000000000..1c06a23dc --- /dev/null +++ b/tests/integration/commands/export/html/markup/11_node_LINK_references_a_document/input1.sdoc @@ -0,0 +1,10 @@ +[DOCUMENT] +TITLE: Document 1 +UID: DOC-1 + +[REQUIREMENT] +UID: REQ-2 +TITLE: Foo Bar +STATEMENT: >>> +Read [LINK: DOC-1] then [LINK: DOC-2]. +<<< diff --git a/tests/integration/commands/export/html/markup/11_node_LINK_references_a_document/input2.sdoc b/tests/integration/commands/export/html/markup/11_node_LINK_references_a_document/input2.sdoc new file mode 100644 index 000000000..07cc08ec1 --- /dev/null +++ b/tests/integration/commands/export/html/markup/11_node_LINK_references_a_document/input2.sdoc @@ -0,0 +1,8 @@ +[DOCUMENT] +TITLE: Document 2 +UID: DOC-2 + +[TEXT] +STATEMENT: >>> +Read [LINK: DOC-2] then [LINK: DOC-1]. +<<< diff --git a/tests/integration/commands/export/html/markup/11_node_LINK_references_a_document/test.itest b/tests/integration/commands/export/html/markup/11_node_LINK_references_a_document/test.itest new file mode 100644 index 000000000..7085c4b97 --- /dev/null +++ b/tests/integration/commands/export/html/markup/11_node_LINK_references_a_document/test.itest @@ -0,0 +1,10 @@ +RUN: %strictdoc export %S --output-dir Output | filecheck %s --dump-input=fail +CHECK: Published: Document 1 + +RUN: %cat %S/Output/html/%THIS_TEST_FOLDER/input1.html | filecheck %s --dump-input=fail --check-prefix CHECK-HTML-DOC1 + +CHECK-HTML-DOC1: Read 🔗 Document 1 then 🔗 Document 2. + +RUN: %cat %S/Output/html/%THIS_TEST_FOLDER/input2.html | filecheck %s --dump-input=fail --check-prefix CHECK-HTML-DOC2 + +CHECK-HTML-DOC2: Read 🔗 Document 2 then 🔗 Document 1. diff --git a/tests/integration/commands/export/rst/52_link_to_document/expected/input1.rst b/tests/integration/commands/export/rst/52_link_to_document/expected/input1.rst new file mode 100644 index 000000000..d67bf1864 --- /dev/null +++ b/tests/integration/commands/export/rst/52_link_to_document/expected/input1.rst @@ -0,0 +1,18 @@ +.. _DOC-1: + +Document 1 +$$$$$$$$$$ + +.. _REQ-2: + +Foo Bar +======= + +.. list-table:: + :align: left + :header-rows: 0 + + * - **UID:** + - REQ-2 + +Read :ref:`Document 1 ` then :ref:`Document 2 `. diff --git a/tests/integration/commands/export/rst/52_link_to_document/expected/input2.rst b/tests/integration/commands/export/rst/52_link_to_document/expected/input2.rst new file mode 100644 index 000000000..54e8d3202 --- /dev/null +++ b/tests/integration/commands/export/rst/52_link_to_document/expected/input2.rst @@ -0,0 +1,6 @@ +.. _DOC-2: + +Document 2 +$$$$$$$$$$ + +Read :ref:`Document 2 ` then :ref:`Document 1 `. diff --git a/tests/integration/commands/export/rst/52_link_to_document/input1.sdoc b/tests/integration/commands/export/rst/52_link_to_document/input1.sdoc new file mode 100644 index 000000000..1c06a23dc --- /dev/null +++ b/tests/integration/commands/export/rst/52_link_to_document/input1.sdoc @@ -0,0 +1,10 @@ +[DOCUMENT] +TITLE: Document 1 +UID: DOC-1 + +[REQUIREMENT] +UID: REQ-2 +TITLE: Foo Bar +STATEMENT: >>> +Read [LINK: DOC-1] then [LINK: DOC-2]. +<<< diff --git a/tests/integration/commands/export/rst/52_link_to_document/input2.sdoc b/tests/integration/commands/export/rst/52_link_to_document/input2.sdoc new file mode 100644 index 000000000..07cc08ec1 --- /dev/null +++ b/tests/integration/commands/export/rst/52_link_to_document/input2.sdoc @@ -0,0 +1,8 @@ +[DOCUMENT] +TITLE: Document 2 +UID: DOC-2 + +[TEXT] +STATEMENT: >>> +Read [LINK: DOC-2] then [LINK: DOC-1]. +<<< diff --git a/tests/integration/commands/export/rst/52_link_to_document/test.itest b/tests/integration/commands/export/rst/52_link_to_document/test.itest new file mode 100644 index 000000000..fd136ab42 --- /dev/null +++ b/tests/integration/commands/export/rst/52_link_to_document/test.itest @@ -0,0 +1,6 @@ +RUN: %strictdoc export %S --formats=rst --output-dir Output + +RUN: %check_exists --file "%S/Output/rst/input1.rst" + +RUN: %diff "%S/Output/rst/input1.rst" "%S/expected/input1.rst" +RUN: %diff "%S/Output/rst/input2.rst" "%S/expected/input2.rst" diff --git a/tests/unit/helpers/test_document_builder.py b/tests/unit/helpers/test_document_builder.py index 72905e8c8..7ebb4dc7f 100644 --- a/tests/unit/helpers/test_document_builder.py +++ b/tests/unit/helpers/test_document_builder.py @@ -15,8 +15,8 @@ class DocumentBuilder: - def __init__(self): - self.document: SDocDocument = self._create_empty_document() + def __init__(self, uid="DOC-1"): + self.document: SDocDocument = self._create_empty_document(uid) self.requirements = [] def add_requirement(self, uid): @@ -77,11 +77,11 @@ def build(self): return self.document @staticmethod - def _create_empty_document() -> SDocDocument: + def _create_empty_document(uid: str) -> SDocDocument: config = DocumentConfig( parent=None, version="0.0.1", - uid="DOC-1", + uid=uid, classification=None, requirement_prefix=None, root=None, diff --git a/tests/unit/strictdoc/core/test_traceability_index.py b/tests/unit/strictdoc/core/test_traceability_index.py index c037486f3..4d78f1c1a 100644 --- a/tests/unit/strictdoc/core/test_traceability_index.py +++ b/tests/unit/strictdoc/core/test_traceability_index.py @@ -133,11 +133,11 @@ def test__adding_parent_link__01__two_requirements_in_one_document(): def test__adding_parent_link__02__two_requirements_in_two_documents(): - document_builder_1 = DocumentBuilder() + document_builder_1 = DocumentBuilder("DOC-1") requirement1 = document_builder_1.add_requirement("REQ-001") document_1 = document_builder_1.build() - document_builder_2 = DocumentBuilder() + document_builder_2 = DocumentBuilder("DOC-2") requirement2 = document_builder_2.add_requirement("REQ-002") document_2 = document_builder_2.build() diff --git a/tests/unit/strictdoc/core/transforms/test_update_requirement.py b/tests/unit/strictdoc/core/transforms/test_update_requirement.py index 5c98f9fef..4e5e01bbe 100644 --- a/tests/unit/strictdoc/core/transforms/test_update_requirement.py +++ b/tests/unit/strictdoc/core/transforms/test_update_requirement.py @@ -323,12 +323,12 @@ def test_25_single_document_remove_child_relation(): def test_26_two_documents_remove_child_relation(): # Document 1 - document_builder = DocumentBuilder() + document_builder = DocumentBuilder("DOC-1") requirement1 = document_builder.add_requirement("REQ-001") document_1 = document_builder.build() # Document 2 - document_builder = DocumentBuilder() + document_builder = DocumentBuilder("DOC-2") requirement2 = document_builder.add_requirement("REQ-002") document_builder.add_requirement_relation( relation_type="Child",