From 972d3109a808b9f87ff9d746da635dcf9c988ef9 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Mon, 22 Jun 2026 12:40:56 +0200 Subject: [PATCH 1/2] fix: needpie coverage --- docs/how-to/dashboards_and_quality_gates.rst | 12 ++++---- .../requirements/requirement_coverage.rst | 6 ++-- .../requirements/tooling_verification.rst | 11 -------- .../score_metrics/sphinx_filters.py | 28 +++++++++++++++++++ 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/docs/how-to/dashboards_and_quality_gates.rst b/docs/how-to/dashboards_and_quality_gates.rst index 353536397..f10607c89 100644 --- a/docs/how-to/dashboards_and_quality_gates.rst +++ b/docs/how-to/dashboards_and_quality_gates.rst @@ -183,10 +183,10 @@ Example 1: Overall view (including remaining/unlinked) .. code-block:: rst - .. needpie:: Overall Requirement Coverage - :labels: Remaining (no selected links), With Test Link, With Code Link, Fully Linked + .. needpie:: Overall Requirement Coverage (non-overlapping) + :labels: Remaining (no links), Test Link Only, Code Link Only, Fully Linked (Both) :colors: #4E79A7, #F28E2B, #59A14F, #B07AA1 - :filter-func: score_metrics.sphinx_filters.get_metrics_with_first_value_total(overall_metrics:total,overall_metrics:with_test_link,overall_metrics:with_code_link,overall_metrics:fully_linked) + :filter-func: score_metrics.sphinx_filters.get_non_overlapping_link_metrics This chart shows: @@ -195,10 +195,10 @@ This chart shows: - requirements with code link, - fully linked requirements. -.. needpie:: Overall Requirement Coverage - :labels: Remaining (no selected links), With Test Link, With Code Link, Fully Linked +.. needpie:: Overall Requirement Coverage (non-overlapping) + :labels: Remaining (no links), Test Link Only, Code Link Only, Fully Linked (Both) :colors: #4E79A7, #F28E2B, #59A14F, #B07AA1 - :filter-func: score_metrics.sphinx_filters.get_metrics_with_first_value_total(overall_metrics:total,overall_metrics:with_test_link,overall_metrics:with_code_link,overall_metrics:fully_linked) + :filter-func: score_metrics.sphinx_filters.get_non_overlapping_link_metrics Example 2: Focused view (no total-based remainder) -------------------------------------------------- diff --git a/docs/internals/requirements/requirement_coverage.rst b/docs/internals/requirements/requirement_coverage.rst index d150be78d..db83a227c 100644 --- a/docs/internals/requirements/requirement_coverage.rst +++ b/docs/internals/requirements/requirement_coverage.rst @@ -25,10 +25,10 @@ by CI quality gates — they will always match. Overall Coverage ---------------- -.. needpie:: Overall Requirement Coverage - :labels: Remaining (no selected links), With Test Link, With Code Link, Fully Linked +.. needpie:: Overall Requirement Coverage (non-overlapping) + :labels: Remaining (no links), Test Link Only, Code Link Only, Fully Linked (Both) :colors: #ca2828, #009ad2, #d26403, #37a12d - :filter-func: score_metrics.sphinx_filters.get_metrics_with_first_value_total(overall_metrics:total,overall_metrics:with_test_link,overall_metrics:with_code_link,overall_metrics:fully_linked) + :filter-func: score_metrics.sphinx_filters.get_non_overlapping_link_metrics .. needpie:: Test Linkages :labels: Tests Not Linked, Tests Linked diff --git a/docs/internals/requirements/tooling_verification.rst b/docs/internals/requirements/tooling_verification.rst index a78d45d84..5b477043d 100644 --- a/docs/internals/requirements/tooling_verification.rst +++ b/docs/internals/requirements/tooling_verification.rst @@ -53,17 +53,6 @@ Overview No skipped or disabled tests are expected in the current dataset. -How many requirements are linked ---------------------------------- - -*This shows how many of our requirements are linked with tests, in source code, both or neither.* - -.. needpie:: Overall Requirement Coverage - :labels: Remaining (no selected links), With Test Link, With Code Link, Fully Linked - :colors: #4E79A7, #F28E2B, #59A14F, #B07AA1 - :filter-func: score_metrics.sphinx_filters.get_metrics_with_first_value_total(overall_metrics:total,overall_metrics:with_test_link,overall_metrics:with_code_link,overall_metrics:fully_linked) - - Testcase Metadata Overview -------------------------- diff --git a/src/extensions/score_metrics/sphinx_filters.py b/src/extensions/score_metrics/sphinx_filters.py index 5f0bfe6eb..a2c6deb6a 100644 --- a/src/extensions/score_metrics/sphinx_filters.py +++ b/src/extensions/score_metrics/sphinx_filters.py @@ -218,3 +218,31 @@ def get_just_metrics(needs: list[Any], results: list[int], **kwargs: Any) -> Non """ results.clear() _get_key_values(results, [str(value) for value in kwargs.values()]) + + +def get_non_overlapping_link_metrics( + needs: list[Any], results: list[int], **kwargs: Any +) -> None: + """Compute mutually exclusive (non-overlapping) requirements-tests linkage categories. + + Use input from global state and overrides results input. + + 1. **Remaining** — no testlink, no source_code_link + 2. **Test link only** — has testlink, no source_code_link + 3. **Code link only** — has source_code_link, no testlink + 4. **Fully linked** — has both testlink and source_code_link + + Suitable for ``needpie`` directives where overlapping + categories produce misleading visualisations. + """ + results.clear() + total = int(CALCULATED_METRICS["overall_metrics"]["total"]) + with_test = int(CALCULATED_METRICS["overall_metrics"]["with_test_link"]) + with_code = int(CALCULATED_METRICS["overall_metrics"]["with_code_link"]) + fully = int(CALCULATED_METRICS["overall_metrics"]["fully_linked"]) + + remaining = total - with_test - with_code + fully # inclusion-exclusion + only_test = with_test - fully + only_code = with_code - fully + + results.extend([remaining, only_test, only_code, fully]) From 238c684cf0c9491ff05b0d2d45be48a091f16ea0 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Mon, 22 Jun 2026 14:17:06 +0200 Subject: [PATCH 2/2] fix: type error --- src/extensions/score_metrics/traceability_metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extensions/score_metrics/traceability_metrics.py b/src/extensions/score_metrics/traceability_metrics.py index 66a1770e0..07e40e0b0 100644 --- a/src/extensions/score_metrics/traceability_metrics.py +++ b/src/extensions/score_metrics/traceability_metrics.py @@ -28,7 +28,7 @@ from sphinx_needs.data import NeedsView, SphinxNeedsData from sphinx_needs.need_item import NeedItem -CALCULATED_METRICS: dict[str, object] = {} +CALCULATED_METRICS: dict[str, Any] = {} def get_need_types_by_tags(needs: list[ScoreNeedType], tags: set[str]) -> list[str]: