diff --git a/docs/directives/list2need.rst b/docs/directives/list2need.rst index 99e21bab8..924a3182a 100644 --- a/docs/directives/list2need.rst +++ b/docs/directives/list2need.rst @@ -149,6 +149,26 @@ The amount of given link-types must be the amount of used levels minus 1. * (NEED-D)Recalculate hash and compare +tags +~~~~ + +``tags`` sets tags globally to all items in the list. + +.. code-block:: rst + + .. list2need:: + :types: req, spec + :tags: A, B + + * (NEED-A)Login user + * (NEED-B)Provide login screen + * (NEED-C)Create password hash + * (NEED-D)Recalculate hash and compare + + +The tags ``A`` and ``B`` are attached to all ``NEED-A``, ``NEED-B``, ``NEED-C`` and ``NEED-D``. + + List examples ------------- diff --git a/sphinx_needs/directives/list2need.py b/sphinx_needs/directives/list2need.py index 3f2a1d79c..ec50b6b12 100644 --- a/sphinx_needs/directives/list2need.py +++ b/sphinx_needs/directives/list2need.py @@ -57,6 +57,7 @@ def presentation(argument: str) -> Any: "delimiter": directives.unchanged, "presentation": directives.unchanged, "links-down": directives.unchanged, + "tags": directives.unchanged, } def run(self) -> Sequence[nodes.Node]: @@ -106,6 +107,10 @@ def run(self) -> Sequence[nodes.Node]: f"Unknown link configured: {down_link_raw}. " f"Allowed are {', '.join(link_types)}" ) + + # Retrieve tags defined at list level + tags = self.options.get("tags", "") + list_needs = [] # Storing the data in a sorted list for content_line in content_raw.split("\n"): @@ -190,6 +195,16 @@ def run(self) -> Sequence[nodes.Node]: list_need["title"] = OPTION_AREA_REGEX.sub("", list_need["title"]) list_need["content"] = OPTION_AREA_REGEX.sub("", list_need["content"]) + # Add tags defined at list level (if exists) to the ones potentially defined in the content + if tags: + if "options" not in list_need: + list_need["options"] = {} + current_tags = list_need["options"].get("tags", "") + if current_tags: + list_need["options"]["tags"] = current_tags + "," + tags + else: + list_need["options"]["tags"] = tags + template = Template(NEED_TEMPLATE, autoescape=True) data = list_need diff --git a/tests/__snapshots__/test_list2need.ambr b/tests/__snapshots__/test_list2need.ambr new file mode 100644 index 000000000..6c44aa230 --- /dev/null +++ b/tests/__snapshots__/test_list2need.ambr @@ -0,0 +1,1453 @@ +# name: test_doc_list2need_html[test_app0] + dict({ + 'NEED-002': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': ''' + .. spec:: Sub-Need on level 2 + :id: NEED-003 + + + + + .. spec:: Another Sub-Need on level 2 + :id: SP_69FFD + + + Where this sentence will be used + as content, the first one as title. + + .. test:: Sub-Need on level 3 + :id: TC_EA5AF + + + With some rst-syntax supported for + the **content** by :ref:`test` + ''', + 'created_at': '', + 'delete': False, + 'docname': 'index', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Another Need example on level 1 with a given ID', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-002', + 'id_complete': 'NEED-002', + 'id_parent': 'NEED-002', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 26, + 'lineno_content': 32, + 'links': list([ + ]), + 'links_back': list([ + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + 'NEED-003', + 'SP_69FFD', + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'TEST DOCUMENT LIST2NEED', + 'sections': list([ + 'TEST DOCUMENT LIST2NEED', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': None, + 'style': None, + 'tags': list([ + ]), + 'template': None, + 'title': 'Another Need example on level 1 with a given ID', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'story', + 'type_color': '#BFD8D2', + 'type_name': 'User Story', + 'type_prefix': 'US_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'NEED-003': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': '', + 'created_at': '', + 'delete': False, + 'docname': 'index', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Sub-Need on level 2', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-003', + 'id_complete': 'NEED-003', + 'id_parent': 'NEED-003', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 32, + 'lineno_content': 35, + 'links': list([ + ]), + 'links_back': list([ + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': 'NEED-002', + 'parent_needs': list([ + 'NEED-002', + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'TEST DOCUMENT LIST2NEED', + 'sections': list([ + 'TEST DOCUMENT LIST2NEED', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': None, + 'style': None, + 'tags': list([ + ]), + 'template': None, + 'title': 'Sub-Need on level 2', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'spec', + 'type_color': '#FEDCD2', + 'type_name': 'Specification', + 'type_prefix': 'SP_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'NEED-1': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': '', + 'created_at': '', + 'delete': False, + 'docname': 'options', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Need example on level 1 ', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-1', + 'id_complete': 'NEED-1', + 'id_parent': 'NEED-1', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 20, + 'lineno_content': 24, + 'links': list([ + ]), + 'links_back': list([ + 'NEED-3', + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'LIST2NEED OPTIONS', + 'sections': list([ + 'LIST2NEED OPTIONS', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': 'open', + 'style': None, + 'tags': list([ + ]), + 'template': None, + 'title': 'Need example on level 1 ', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'story', + 'type_color': '#BFD8D2', + 'type_name': 'User Story', + 'type_prefix': 'US_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'NEED-2': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': '', + 'created_at': '', + 'delete': False, + 'docname': 'options', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Need example on level 1 ', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-2', + 'id_complete': 'NEED-2', + 'id_parent': 'NEED-2', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 27, + 'lineno_content': 32, + 'links': list([ + ]), + 'links_back': list([ + 'NEED-3', + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'LIST2NEED OPTIONS', + 'sections': list([ + 'LIST2NEED OPTIONS', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': 'done', + 'style': None, + 'tags': list([ + 'tag1', + 'tag2', + 'tag3', + ]), + 'template': None, + 'title': 'Need example on level 1 ', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'story', + 'type_color': '#BFD8D2', + 'type_name': 'User Story', + 'type_prefix': 'US_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'NEED-3': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': '', + 'created_at': '', + 'delete': False, + 'docname': 'options', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Link example ', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-3', + 'id_complete': 'NEED-3', + 'id_parent': 'NEED-3', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 35, + 'lineno_content': 39, + 'links': list([ + 'NEED-1', + 'NEED-2', + ]), + 'links_back': list([ + 'NEED-Z', + 'NEED-4', + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'LIST2NEED OPTIONS', + 'sections': list([ + 'LIST2NEED OPTIONS', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': None, + 'style': None, + 'tags': list([ + ]), + 'template': None, + 'title': 'Link example ', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'story', + 'type_color': '#BFD8D2', + 'type_name': 'User Story', + 'type_prefix': 'US_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'NEED-4': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': 'With some content in the next line.', + 'created_at': '', + 'delete': False, + 'docname': 'options', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'New line example', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-4', + 'id_complete': 'NEED-4', + 'id_parent': 'NEED-4', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 42, + 'lineno_content': 49, + 'links': list([ + 'NEED-3', + ]), + 'links_back': list([ + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'LIST2NEED OPTIONS', + 'sections': list([ + 'LIST2NEED OPTIONS', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': 'in progress', + 'style': None, + 'tags': list([ + ]), + 'template': None, + 'title': 'New line example', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'story', + 'type_color': '#BFD8D2', + 'type_name': 'User Story', + 'type_prefix': 'US_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'NEED-A': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + 'NEED-B', + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': '', + 'created_at': '', + 'delete': False, + 'docname': 'links_down', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Need example on level 1', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-A', + 'id_complete': 'NEED-A', + 'id_parent': 'NEED-A', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 19, + 'lineno_content': 23, + 'links': list([ + ]), + 'links_back': list([ + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'LIST2NEED LINKS_DOWN', + 'sections': list([ + 'LIST2NEED LINKS_DOWN', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': None, + 'style': None, + 'tags': list([ + ]), + 'template': None, + 'title': 'Need example on level 1', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'story', + 'type_color': '#BFD8D2', + 'type_name': 'User Story', + 'type_prefix': 'US_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'NEED-B': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + 'NEED-A', + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': '', + 'created_at': '', + 'delete': False, + 'docname': 'links_down', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Need example on level 2', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-B', + 'id_complete': 'NEED-B', + 'id_parent': 'NEED-B', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 25, + 'lineno_content': 29, + 'links': list([ + ]), + 'links_back': list([ + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'LIST2NEED LINKS_DOWN', + 'sections': list([ + 'LIST2NEED LINKS_DOWN', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': None, + 'style': None, + 'tags': list([ + ]), + 'template': None, + 'title': 'Need example on level 2', + 'triggers': list([ + 'NEED-C', + ]), + 'triggers_back': list([ + ]), + 'type': 'spec', + 'type_color': '#FEDCD2', + 'type_name': 'Specification', + 'type_prefix': 'SP_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'NEED-C': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': '', + 'created_at': '', + 'delete': False, + 'docname': 'links_down', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Need example on level 3', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-C', + 'id_complete': 'NEED-C', + 'id_parent': 'NEED-C', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 31, + 'lineno_content': 34, + 'links': list([ + ]), + 'links_back': list([ + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'LIST2NEED LINKS_DOWN', + 'sections': list([ + 'LIST2NEED LINKS_DOWN', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': None, + 'style': None, + 'tags': list([ + ]), + 'template': None, + 'title': 'Need example on level 3', + 'triggers': list([ + ]), + 'triggers_back': list([ + 'NEED-B', + ]), + 'type': 'test', + 'type_color': '#DCB239', + 'type_name': 'Test Case', + 'type_prefix': 'TC_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'NEED-W': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': '', + 'created_at': '', + 'delete': False, + 'docname': 'global_tags', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Need example on level 1 ', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-W', + 'id_complete': 'NEED-W', + 'id_parent': 'NEED-W', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 21, + 'lineno_content': 26, + 'links': list([ + ]), + 'links_back': list([ + 'NEED-Y', + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'LIST2NEED GLOBAL TAGS', + 'sections': list([ + 'LIST2NEED GLOBAL TAGS', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': 'open', + 'style': None, + 'tags': list([ + 'global_tag1', + 'global_tag2', + 'global_tag3', + ]), + 'template': None, + 'title': 'Need example on level 1 ', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'story', + 'type_color': '#BFD8D2', + 'type_name': 'User Story', + 'type_prefix': 'US_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'NEED-X': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': '', + 'created_at': '', + 'delete': False, + 'docname': 'global_tags', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Need example on level 1 ', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-X', + 'id_complete': 'NEED-X', + 'id_parent': 'NEED-X', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 29, + 'lineno_content': 34, + 'links': list([ + ]), + 'links_back': list([ + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'LIST2NEED GLOBAL TAGS', + 'sections': list([ + 'LIST2NEED GLOBAL TAGS', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': 'done', + 'style': None, + 'tags': list([ + 'tag1', + 'tag2', + 'tag3', + 'global_tag1', + 'global_tag2', + 'global_tag3', + ]), + 'template': None, + 'title': 'Need example on level 1 ', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'story', + 'type_color': '#BFD8D2', + 'type_name': 'User Story', + 'type_prefix': 'US_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'NEED-Y': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': '', + 'created_at': '', + 'delete': False, + 'docname': 'global_tags', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Link example ', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-Y', + 'id_complete': 'NEED-Y', + 'id_parent': 'NEED-Y', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 37, + 'lineno_content': 42, + 'links': list([ + 'NEED-W', + 'NEED-Y', + ]), + 'links_back': list([ + 'NEED-Y', + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'LIST2NEED GLOBAL TAGS', + 'sections': list([ + 'LIST2NEED GLOBAL TAGS', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': None, + 'style': None, + 'tags': list([ + 'global_tag1', + 'global_tag2', + 'global_tag3', + ]), + 'template': None, + 'title': 'Link example ', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'story', + 'type_color': '#BFD8D2', + 'type_name': 'User Story', + 'type_prefix': 'US_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'NEED-Z': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': 'With some content in the next line.', + 'created_at': '', + 'delete': False, + 'docname': 'global_tags', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'New line example', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'NEED-Z', + 'id_complete': 'NEED-Z', + 'id_parent': 'NEED-Z', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 45, + 'lineno_content': 53, + 'links': list([ + 'NEED-3', + ]), + 'links_back': list([ + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'LIST2NEED GLOBAL TAGS', + 'sections': list([ + 'LIST2NEED GLOBAL TAGS', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': 'in progress', + 'style': None, + 'tags': list([ + 'global_tag1', + 'global_tag2', + 'global_tag3', + ]), + 'template': None, + 'title': 'New line example', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'story', + 'type_color': '#BFD8D2', + 'type_name': 'User Story', + 'type_prefix': 'US_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'SP_69FFD': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': ''' + Where this sentence will be used + as content, the first one as title. + + .. test:: Sub-Need on level 3 + :id: TC_EA5AF + + + With some rst-syntax supported for + the **content** by :ref:`test` + ''', + 'created_at': '', + 'delete': False, + 'docname': 'index', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Another Sub-Need on level 2', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'SP_69FFD', + 'id_complete': 'SP_69FFD', + 'id_parent': 'SP_69FFD', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 38, + 'lineno_content': 42, + 'links': list([ + ]), + 'links_back': list([ + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': 'NEED-002', + 'parent_needs': list([ + 'NEED-002', + ]), + 'parent_needs_back': list([ + 'TC_EA5AF', + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'TEST DOCUMENT LIST2NEED', + 'sections': list([ + 'TEST DOCUMENT LIST2NEED', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': None, + 'style': None, + 'tags': list([ + ]), + 'template': None, + 'title': 'Another Sub-Need on level 2', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'spec', + 'type_color': '#FEDCD2', + 'type_name': 'Specification', + 'type_prefix': 'SP_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'TC_EA5AF': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': ''' + With some rst-syntax supported for + the **content** by :ref:`test` + ''', + 'created_at': '', + 'delete': False, + 'docname': 'index', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Sub-Need on level 3', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'TC_EA5AF', + 'id_complete': 'TC_EA5AF', + 'id_parent': 'TC_EA5AF', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 45, + 'lineno_content': 49, + 'links': list([ + ]), + 'links_back': list([ + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': 'SP_69FFD', + 'parent_needs': list([ + 'SP_69FFD', + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'TEST DOCUMENT LIST2NEED', + 'sections': list([ + 'TEST DOCUMENT LIST2NEED', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': None, + 'style': None, + 'tags': list([ + ]), + 'template': None, + 'title': 'Sub-Need on level 3', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'test', + 'type_color': '#DCB239', + 'type_name': 'Test Case', + 'type_prefix': 'TC_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + 'US_F1B63': dict({ + 'arch': dict({ + }), + 'avatar': '', + 'checks': list([ + ]), + 'checks_back': list([ + ]), + 'closed_at': '', + 'collapse': False, + 'completion': '', + 'constraints': list([ + ]), + 'constraints_passed': True, + 'constraints_results': dict({ + }), + 'content': '', + 'created_at': '', + 'delete': False, + 'docname': 'index', + 'doctype': '.rst', + 'duration': '', + 'external_css': 'external_link', + 'external_url': None, + 'full_title': 'Need example on level 1', + 'has_dead_links': False, + 'has_forbidden_dead_links': False, + 'hide': False, + 'id': 'US_F1B63', + 'id_complete': 'US_F1B63', + 'id_parent': 'US_F1B63', + 'id_prefix': '', + 'is_external': False, + 'is_modified': False, + 'is_need': True, + 'is_part': False, + 'jinja_content': False, + 'layout': '', + 'lineno': 20, + 'lineno_content': 23, + 'links': list([ + ]), + 'links_back': list([ + ]), + 'max_amount': '', + 'max_content_lines': '', + 'modifications': 0, + 'params': '', + 'parent_need': '', + 'parent_needs': list([ + ]), + 'parent_needs_back': list([ + ]), + 'parts': dict({ + }), + 'post_template': None, + 'pre_template': None, + 'prefix': '', + 'query': '', + 'section_name': 'TEST DOCUMENT LIST2NEED', + 'sections': list([ + 'TEST DOCUMENT LIST2NEED', + ]), + 'service': '', + 'signature': '', + 'specific': '', + 'status': None, + 'style': None, + 'tags': list([ + ]), + 'template': None, + 'title': 'Need example on level 1', + 'triggers': list([ + ]), + 'triggers_back': list([ + ]), + 'type': 'story', + 'type_color': '#BFD8D2', + 'type_name': 'User Story', + 'type_prefix': 'US_', + 'type_style': 'node', + 'updated_at': '', + 'url': '', + 'url_postfix': '', + 'user': '', + }), + }) +# --- diff --git a/tests/doc_test/doc_list2need/global_tags.rst b/tests/doc_test/doc_list2need/global_tags.rst new file mode 100644 index 000000000..fc1129e49 --- /dev/null +++ b/tests/doc_test/doc_list2need/global_tags.rst @@ -0,0 +1,19 @@ +LIST2NEED GLOBAL TAGS +===================== + + +.. list2need:: + :types: story, spec, test + :presentation: nested + :delimiter: . + :tags: global_tag1, global_tag2, global_tag3 + + * (NEED-W)Need example on level 1 ((status="open")) + * (NEED-X)Need example on level 1 ((status="done", tags="tag1, tag2, tag3")) + * (NEED-Y)Link example ((links="NEED-W, NEED-Y")) + * (NEED-Z)New line example. + With some content in the next line. + ((status="in progress", links="NEED-3")) + + + diff --git a/tests/doc_test/doc_list2need/index.rst b/tests/doc_test/doc_list2need/index.rst index bd56d3c56..3c9e009c9 100644 --- a/tests/doc_test/doc_list2need/index.rst +++ b/tests/doc_test/doc_list2need/index.rst @@ -27,4 +27,5 @@ Foo Bar. .. toctree:: options - links_down \ No newline at end of file + links_down + global_tags \ No newline at end of file diff --git a/tests/test_list2need.py b/tests/test_list2need.py index 605f4331f..d4c272227 100644 --- a/tests/test_list2need.py +++ b/tests/test_list2need.py @@ -2,15 +2,22 @@ import pytest +from sphinx_needs.api import get_needs_view + @pytest.mark.parametrize( "test_app", [{"buildername": "html", "srcdir": "doc_test/doc_list2need"}], indirect=True, ) -def test_doc_list2need_html(test_app): +def test_doc_list2need_html(test_app, snapshot): app = test_app app.build() + assert app._warning.getvalue() == "" + + view = get_needs_view(app) + assert dict(view) == snapshot + index_html = Path(app.outdir, "index.html").read_text() assert "NEED-002" in index_html assert "Sub-Need on level 3" in index_html