@elisra-devops/docgen-data-provider 1.86.0 → 1.87.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -142,6 +142,7 @@ export default class ResultDataProvider {
142
142
  private isExcludedL3L4BySapWbs;
143
143
  private normalizeMewpRequirementCode;
144
144
  private normalizeMewpRequirementCodeWithSuffix;
145
+ private formatRequirementCodesGroupedByFamily;
145
146
  private toMewpComparableText;
146
147
  private fetchTestPlanName;
147
148
  /**
@@ -581,17 +581,34 @@ class ResultDataProvider {
581
581
  const missingFamilyMembers = new Set();
582
582
  for (const [baseKey, mentionedCodes] of mentionedCodesByBase.entries()) {
583
583
  const familyCodes = requirementFamilies.get(baseKey);
584
+ const mentionedCodesList = [...mentionedCodes];
585
+ const hasBaseMention = mentionedCodesList.some((code) => !/-\d+$/.test(code));
586
+ const mentionedSpecificMembers = mentionedCodesList.filter((code) => /-\d+$/.test(code));
584
587
  if (familyCodes === null || familyCodes === void 0 ? void 0 : familyCodes.size) {
585
- const missingInFamily = [...familyCodes].filter((code) => !linkedFullCodes.has(code));
586
- if (missingInFamily.length === 0)
588
+ // Base mention ("SR0054") validates against child coverage when children exist.
589
+ // If no child variants exist, fallback to the single standalone requirement code.
590
+ if (hasBaseMention) {
591
+ const familyCodesList = [...familyCodes];
592
+ const childFamilyCodes = familyCodesList.filter((code) => /-\d+$/.test(code));
593
+ const targetFamilyCodes = childFamilyCodes.length > 0 ? childFamilyCodes : familyCodesList;
594
+ const missingInTargetFamily = targetFamilyCodes.filter((code) => !linkedFullCodes.has(code));
595
+ if (missingInTargetFamily.length > 0) {
596
+ const hasAnyLinkedInFamily = familyCodesList.some((code) => linkedFullCodes.has(code));
597
+ if (!hasAnyLinkedInFamily) {
598
+ missingBaseWhenFamilyUncovered.add(baseKey);
599
+ }
600
+ else {
601
+ for (const code of missingInTargetFamily) {
602
+ missingFamilyMembers.add(code);
603
+ }
604
+ }
605
+ }
587
606
  continue;
588
- const linkedInFamilyCount = familyCodes.size - missingInFamily.length;
589
- if (linkedInFamilyCount === 0) {
590
- missingBaseWhenFamilyUncovered.add(baseKey);
591
607
  }
592
- else {
593
- for (const code of missingInFamily) {
594
- missingFamilyMembers.add(code);
608
+ // Specific mention ("SR0054-1") validates as exact-match only.
609
+ for (const code of mentionedSpecificMembers) {
610
+ if (!linkedFullCodes.has(code)) {
611
+ missingSpecificMentionedNoFamily.add(code);
595
612
  }
596
613
  }
597
614
  continue;
@@ -661,11 +678,11 @@ class ResultDataProvider {
661
678
  return String(a[0]).localeCompare(String(b[0]));
662
679
  })
663
680
  .map(([stepRef, requirementIds]) => {
664
- const requirementList = [...requirementIds].sort((a, b) => a.localeCompare(b));
665
- return `${stepRef}: ${requirementList.join(', ')}`;
681
+ const groupedRequirementList = this.formatRequirementCodesGroupedByFamily(requirementIds);
682
+ return `${stepRef}: ${groupedRequirementList}`;
666
683
  })
667
684
  .join('; ');
668
- const linkedButNotMentioned = sortedExtraLinked.join('; ');
685
+ const linkedButNotMentioned = this.formatRequirementCodesGroupedByFamily(sortedExtraLinked);
669
686
  const validationStatus = mentionedButNotLinked || linkedButNotMentioned ? 'Fail' : 'Pass';
670
687
  if (validationStatus === 'Fail')
671
688
  diagnostics.failingRows += 1;
@@ -2254,6 +2271,29 @@ class ResultDataProvider {
2254
2271
  return `SR${match[1]}-${match[2]}`;
2255
2272
  return `SR${match[1]}`;
2256
2273
  }
2274
+ formatRequirementCodesGroupedByFamily(codes) {
2275
+ const byBaseKey = new Map();
2276
+ for (const rawCode of codes || []) {
2277
+ const normalizedCode = this.normalizeMewpRequirementCodeWithSuffix(String(rawCode || ''));
2278
+ if (!normalizedCode)
2279
+ continue;
2280
+ const baseKey = this.toRequirementKey(normalizedCode) || normalizedCode;
2281
+ if (!byBaseKey.has(baseKey))
2282
+ byBaseKey.set(baseKey, new Set());
2283
+ byBaseKey.get(baseKey).add(normalizedCode);
2284
+ }
2285
+ if (byBaseKey.size === 0)
2286
+ return '';
2287
+ return [...byBaseKey.entries()]
2288
+ .sort((a, b) => a[0].localeCompare(b[0]))
2289
+ .map(([baseKey, members]) => {
2290
+ const sortedMembers = [...members].sort((a, b) => a.localeCompare(b));
2291
+ if (sortedMembers.length <= 1)
2292
+ return sortedMembers[0];
2293
+ return `${baseKey}: ${sortedMembers.join(', ')}`;
2294
+ })
2295
+ .join('; ');
2296
+ }
2257
2297
  toMewpComparableText(value) {
2258
2298
  if (value === null || value === undefined)
2259
2299
  return '';