api-tests-coverage 1.0.22 → 1.0.24

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.
Files changed (175) hide show
  1. package/README.md +39 -0
  2. package/config.yaml.example +35 -0
  3. package/dist/dashboard/dist/assets/_basePickBy-BamgEusj.js +1 -0
  4. package/dist/dashboard/dist/assets/_basePickBy-D4Hl8chy.js +1 -0
  5. package/dist/dashboard/dist/assets/_baseUniq-BBhq12Ja.js +1 -0
  6. package/dist/dashboard/dist/assets/_baseUniq-BSUUnV_V.js +1 -0
  7. package/dist/dashboard/dist/assets/arc-Dh-qL1ea.js +1 -0
  8. package/dist/dashboard/dist/assets/arc-DhDluTY5.js +1 -0
  9. package/dist/dashboard/dist/assets/architectureDiagram-VXUJARFQ-BxQ_anmt.js +36 -0
  10. package/dist/dashboard/dist/assets/architectureDiagram-VXUJARFQ-DGlUU7dC.js +36 -0
  11. package/dist/dashboard/dist/assets/blockDiagram-VD42YOAC-CgXi3kEZ.js +122 -0
  12. package/dist/dashboard/dist/assets/blockDiagram-VD42YOAC-Krm3lc7z.js +122 -0
  13. package/dist/dashboard/dist/assets/c4Diagram-YG6GDRKO-Cfd4OeWg.js +10 -0
  14. package/dist/dashboard/dist/assets/c4Diagram-YG6GDRKO-Cr3xB15y.js +10 -0
  15. package/dist/dashboard/dist/assets/channel-DYAie-7m.js +1 -0
  16. package/dist/dashboard/dist/assets/channel-a4t2URTe.js +1 -0
  17. package/dist/dashboard/dist/assets/chunk-4BX2VUAB-BaW3__pI.js +1 -0
  18. package/dist/dashboard/dist/assets/chunk-4BX2VUAB-ljBQ5lHA.js +1 -0
  19. package/dist/dashboard/dist/assets/chunk-55IACEB6-Cikrdc3Q.js +1 -0
  20. package/dist/dashboard/dist/assets/chunk-55IACEB6-DyYevfEQ.js +1 -0
  21. package/dist/dashboard/dist/assets/chunk-B4BG7PRW-C2bwZFec.js +165 -0
  22. package/dist/dashboard/dist/assets/chunk-B4BG7PRW-dtHgbkmj.js +165 -0
  23. package/dist/dashboard/dist/assets/chunk-DI55MBZ5-Cv3hm2Ke.js +220 -0
  24. package/dist/dashboard/dist/assets/chunk-DI55MBZ5-DO0T2xne.js +220 -0
  25. package/dist/dashboard/dist/assets/chunk-FMBD7UC4-CCYA4j_f.js +15 -0
  26. package/dist/dashboard/dist/assets/chunk-FMBD7UC4-Ds1_OqKH.js +15 -0
  27. package/dist/dashboard/dist/assets/chunk-QN33PNHL-B6zkzIAo.js +1 -0
  28. package/dist/dashboard/dist/assets/chunk-QN33PNHL-Cdhqs7xo.js +1 -0
  29. package/dist/dashboard/dist/assets/chunk-QZHKN3VN-BzHw38Ki.js +1 -0
  30. package/dist/dashboard/dist/assets/chunk-QZHKN3VN-C7xuA6tl.js +1 -0
  31. package/dist/dashboard/dist/assets/chunk-TZMSLE5B-D_ea_wdP.js +1 -0
  32. package/dist/dashboard/dist/assets/chunk-TZMSLE5B-dkJ0rsgF.js +1 -0
  33. package/dist/dashboard/dist/assets/classDiagram-2ON5EDUG-B6SxXE6T.js +1 -0
  34. package/dist/dashboard/dist/assets/classDiagram-2ON5EDUG-DiIv5Pho.js +1 -0
  35. package/dist/dashboard/dist/assets/classDiagram-v2-WZHVMYZB-B6SxXE6T.js +1 -0
  36. package/dist/dashboard/dist/assets/classDiagram-v2-WZHVMYZB-DiIv5Pho.js +1 -0
  37. package/dist/dashboard/dist/assets/clone-B4LorrSy.js +1 -0
  38. package/dist/dashboard/dist/assets/clone-kcKg1tUH.js +1 -0
  39. package/dist/dashboard/dist/assets/cose-bilkent-S5V4N54A-DasyAK5c.js +1 -0
  40. package/dist/dashboard/dist/assets/cose-bilkent-S5V4N54A-jzGbyPIS.js +1 -0
  41. package/dist/dashboard/dist/assets/dagre-6UL2VRFP-D7rgvBx1.js +4 -0
  42. package/dist/dashboard/dist/assets/dagre-6UL2VRFP-m-5bs635.js +4 -0
  43. package/dist/dashboard/dist/assets/diagram-PSM6KHXK-2rYklqon.js +24 -0
  44. package/dist/dashboard/dist/assets/diagram-PSM6KHXK-CYFwwEdy.js +24 -0
  45. package/dist/dashboard/dist/assets/diagram-QEK2KX5R-CGrvALqm.js +43 -0
  46. package/dist/dashboard/dist/assets/diagram-QEK2KX5R-m4Fda1GA.js +43 -0
  47. package/dist/dashboard/dist/assets/diagram-S2PKOQOG-BDVk4AKU.js +24 -0
  48. package/dist/dashboard/dist/assets/diagram-S2PKOQOG-DA3c-QP4.js +24 -0
  49. package/dist/dashboard/dist/assets/erDiagram-Q2GNP2WA-3-jAbxQ6.js +60 -0
  50. package/dist/dashboard/dist/assets/erDiagram-Q2GNP2WA-BsYH8cLH.js +60 -0
  51. package/dist/dashboard/dist/assets/flowDiagram-NV44I4VS-Cfv1hkQB.js +162 -0
  52. package/dist/dashboard/dist/assets/flowDiagram-NV44I4VS-Da_JhBCy.js +162 -0
  53. package/dist/dashboard/dist/assets/ganttDiagram-JELNMOA3-B7GZPGck.js +267 -0
  54. package/dist/dashboard/dist/assets/ganttDiagram-JELNMOA3-D8FTswNn.js +267 -0
  55. package/dist/dashboard/dist/assets/gitGraphDiagram-V2S2FVAM-BFJR-ITH.js +65 -0
  56. package/dist/dashboard/dist/assets/gitGraphDiagram-V2S2FVAM-K8X-_4av.js +65 -0
  57. package/dist/dashboard/dist/assets/graph-CIvnjOQQ.js +1 -0
  58. package/dist/dashboard/dist/assets/graph-CfuGK9GG.js +1 -0
  59. package/dist/dashboard/dist/assets/index-BWX0sSZn.css +1 -0
  60. package/dist/dashboard/dist/assets/index-CbAFWEor.js +777 -0
  61. package/dist/dashboard/dist/assets/index-DS-KIxwV.js +777 -0
  62. package/dist/dashboard/dist/assets/infoDiagram-HS3SLOUP-CaIaIUhT.js +2 -0
  63. package/dist/dashboard/dist/assets/infoDiagram-HS3SLOUP-OcK0Lxgi.js +2 -0
  64. package/dist/dashboard/dist/assets/journeyDiagram-XKPGCS4Q-D6dwPswq.js +139 -0
  65. package/dist/dashboard/dist/assets/journeyDiagram-XKPGCS4Q-DTJukVOY.js +139 -0
  66. package/dist/dashboard/dist/assets/kanban-definition-3W4ZIXB7-CERyhhrH.js +89 -0
  67. package/dist/dashboard/dist/assets/kanban-definition-3W4ZIXB7-Di65fNuD.js +89 -0
  68. package/dist/dashboard/dist/assets/layout-DAt24RVX.js +1 -0
  69. package/dist/dashboard/dist/assets/layout-v7cCi3Fl.js +1 -0
  70. package/dist/dashboard/dist/assets/mindmap-definition-VGOIOE7T-BvNtTz8N.js +68 -0
  71. package/dist/dashboard/dist/assets/mindmap-definition-VGOIOE7T-DxI8MXCF.js +68 -0
  72. package/dist/dashboard/dist/assets/pieDiagram-ADFJNKIX-BafKx3_Y.js +30 -0
  73. package/dist/dashboard/dist/assets/pieDiagram-ADFJNKIX-Cjg80C_b.js +30 -0
  74. package/dist/dashboard/dist/assets/quadrantDiagram-AYHSOK5B-BcZsArkk.js +7 -0
  75. package/dist/dashboard/dist/assets/quadrantDiagram-AYHSOK5B-YtFFUYGD.js +7 -0
  76. package/dist/dashboard/dist/assets/requirementDiagram-UZGBJVZJ-CqFAO2t6.js +64 -0
  77. package/dist/dashboard/dist/assets/requirementDiagram-UZGBJVZJ-DLV2LTE5.js +64 -0
  78. package/dist/dashboard/dist/assets/sankeyDiagram-TZEHDZUN-C6_Urrii.js +10 -0
  79. package/dist/dashboard/dist/assets/sankeyDiagram-TZEHDZUN-CqSaCg-3.js +10 -0
  80. package/dist/dashboard/dist/assets/sequenceDiagram-WL72ISMW-6IXD1uqW.js +145 -0
  81. package/dist/dashboard/dist/assets/sequenceDiagram-WL72ISMW-D33UwAtz.js +145 -0
  82. package/dist/dashboard/dist/assets/stateDiagram-FKZM4ZOC-DSp83t9D.js +1 -0
  83. package/dist/dashboard/dist/assets/stateDiagram-FKZM4ZOC-DvSVQAfp.js +1 -0
  84. package/dist/dashboard/dist/assets/stateDiagram-v2-4FDKWEC3-BMFdt0QQ.js +1 -0
  85. package/dist/dashboard/dist/assets/stateDiagram-v2-4FDKWEC3-OTWrEpQO.js +1 -0
  86. package/dist/dashboard/dist/assets/timeline-definition-IT6M3QCI-Cll7Nvth.js +61 -0
  87. package/dist/dashboard/dist/assets/timeline-definition-IT6M3QCI-D5Bb3Jj7.js +61 -0
  88. package/dist/dashboard/dist/assets/treemap-GDKQZRPO-CKbkkwye.js +162 -0
  89. package/dist/dashboard/dist/assets/treemap-GDKQZRPO-DtqX8zNC.js +162 -0
  90. package/dist/dashboard/dist/assets/xychartDiagram-PRI3JC2R-C_Tlzchx.js +7 -0
  91. package/dist/dashboard/dist/assets/xychartDiagram-PRI3JC2R-zxwS9i0A.js +7 -0
  92. package/dist/dashboard/dist/index.html +2 -2
  93. package/dist/dashboard/dist/reports/coverage-summary.json +75 -1
  94. package/dist/dashboard/dist/reports/security-full.json +157 -0
  95. package/dist/src/compatibilityCoverage.d.ts +34 -15
  96. package/dist/src/compatibilityCoverage.d.ts.map +1 -1
  97. package/dist/src/compatibilityCoverage.js +387 -85
  98. package/dist/src/config/defaultConfig.d.ts.map +1 -1
  99. package/dist/src/config/defaultConfig.js +62 -0
  100. package/dist/src/config/schema.d.ts.map +1 -1
  101. package/dist/src/config/schema.js +1 -1
  102. package/dist/src/config/types.d.ts +81 -1
  103. package/dist/src/config/types.d.ts.map +1 -1
  104. package/dist/src/config/validateConfig.d.ts.map +1 -1
  105. package/dist/src/config/validateConfig.js +126 -0
  106. package/dist/src/contracts/compatibilityMatrix.d.ts +20 -0
  107. package/dist/src/contracts/compatibilityMatrix.d.ts.map +1 -0
  108. package/dist/src/contracts/compatibilityMatrix.js +198 -0
  109. package/dist/src/contracts/pactBrokerClient.d.ts +10 -0
  110. package/dist/src/contracts/pactBrokerClient.d.ts.map +1 -0
  111. package/dist/src/contracts/pactBrokerClient.js +117 -0
  112. package/dist/src/contracts/schemaEvolutionChecker.d.ts +17 -0
  113. package/dist/src/contracts/schemaEvolutionChecker.d.ts.map +1 -0
  114. package/dist/src/contracts/schemaEvolutionChecker.js +95 -0
  115. package/dist/src/contracts/springCloudContractParser.d.ts +10 -0
  116. package/dist/src/contracts/springCloudContractParser.d.ts.map +1 -0
  117. package/dist/src/contracts/springCloudContractParser.js +144 -0
  118. package/dist/src/discovery/fileClassifier.d.ts.map +1 -1
  119. package/dist/src/discovery/fileClassifier.js +25 -0
  120. package/dist/src/discovery/projectDiscovery.d.ts +2 -0
  121. package/dist/src/discovery/projectDiscovery.d.ts.map +1 -1
  122. package/dist/src/discovery/projectDiscovery.js +25 -25
  123. package/dist/src/index.js +233 -16
  124. package/dist/src/inference/routeInference.d.ts +10 -2
  125. package/dist/src/inference/routeInference.d.ts.map +1 -1
  126. package/dist/src/inference/routeInference.js +363 -62
  127. package/dist/src/languageDetection.d.ts.map +1 -1
  128. package/dist/src/languageDetection.js +21 -4
  129. package/dist/src/lib/index.d.ts +3 -0
  130. package/dist/src/lib/index.d.ts.map +1 -1
  131. package/dist/src/lib/index.js +3 -1
  132. package/dist/src/pipeline/stages/tia/parameterizedTestExpander.js +152 -79
  133. package/dist/src/pipeline/stages/tia/testEndpointMapper.d.ts +5 -1
  134. package/dist/src/pipeline/stages/tia/testEndpointMapper.d.ts.map +1 -1
  135. package/dist/src/pipeline/stages/tia/testEndpointMapper.js +356 -42
  136. package/dist/src/pipeline/stages/tia/testLayerClassifier.d.ts.map +1 -1
  137. package/dist/src/pipeline/stages/tia/testLayerClassifier.js +20 -5
  138. package/dist/src/pipeline/stages/tia/tiaStage.d.ts.map +1 -1
  139. package/dist/src/pipeline/stages/tia/tiaStage.js +3 -1
  140. package/dist/src/pipeline/stages/tia/types.d.ts +11 -2
  141. package/dist/src/pipeline/stages/tia/types.d.ts.map +1 -1
  142. package/dist/src/projectDefaults.d.ts +6 -0
  143. package/dist/src/projectDefaults.d.ts.map +1 -0
  144. package/dist/src/projectDefaults.js +43 -0
  145. package/dist/src/security/hub.d.ts +81 -0
  146. package/dist/src/security/hub.d.ts.map +1 -0
  147. package/dist/src/security/hub.js +420 -0
  148. package/dist/src/security/index.d.ts +1 -0
  149. package/dist/src/security/index.d.ts.map +1 -1
  150. package/dist/src/security/index.js +8 -2
  151. package/dist/src/security/normalizers/gitleaks.d.ts +7 -0
  152. package/dist/src/security/normalizers/gitleaks.d.ts.map +1 -0
  153. package/dist/src/security/normalizers/gitleaks.js +32 -0
  154. package/dist/src/security/scanners/gitleaks.d.ts +3 -0
  155. package/dist/src/security/scanners/gitleaks.d.ts.map +1 -0
  156. package/dist/src/security/scanners/gitleaks.js +105 -0
  157. package/dist/src/security/scanners/semgrep.d.ts.map +1 -1
  158. package/dist/src/security/scanners/semgrep.js +24 -2
  159. package/dist/src/security/scanners/trivy.d.ts.map +1 -1
  160. package/dist/src/security/scanners/trivy.js +24 -2
  161. package/dist/src/security/scanners/zap.d.ts.map +1 -1
  162. package/dist/src/security/scanners/zap.js +27 -2
  163. package/dist/src/security/types.d.ts +15 -1
  164. package/dist/src/security/types.d.ts.map +1 -1
  165. package/dist/src/streaming/schema/index.d.ts +23 -0
  166. package/dist/src/streaming/schema/index.d.ts.map +1 -0
  167. package/dist/src/streaming/schema/index.js +196 -0
  168. package/dist/src/summary/markdownRenderer.d.ts.map +1 -1
  169. package/dist/src/summary/markdownRenderer.js +15 -1
  170. package/dist/src/summary/summaryTypes.d.ts.map +1 -1
  171. package/dist/src/summary/summaryTypes.js +1 -0
  172. package/dist/src/unitAnalysis.d.ts +145 -0
  173. package/dist/src/unitAnalysis.d.ts.map +1 -0
  174. package/dist/src/unitAnalysis.js +1392 -0
  175. package/package.json +1 -1
@@ -10,6 +10,8 @@
10
10
  * 5. Framework metadata: Framework annotations link test to endpoint
11
11
  * 6. Helper traversal: URL resolved through helper function chain
12
12
  * 7. Page object: URL resolved through page object pattern
13
+ * 8. Service call: test covers a service method that is linked to an endpoint via call graph
14
+ * 9. Business rule: test method name implies a business rule covered by the test
13
15
  */
14
16
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
17
  if (k2 === undefined) k2 = k;
@@ -46,89 +48,401 @@ var __importStar = (this && this.__importStar) || (function () {
46
48
  })();
47
49
  Object.defineProperty(exports, "__esModule", { value: true });
48
50
  exports.mapTestsToEndpoints = mapTestsToEndpoints;
51
+ const testLayerClassifier_1 = require("./testLayerClassifier");
52
+ const parameterizedTestExpander_1 = require("./parameterizedTestExpander");
53
+ const fs = __importStar(require("fs"));
49
54
  const path = __importStar(require("path"));
50
55
  /**
51
56
  * Map test files to endpoints using available evidence in the graph.
52
57
  *
53
58
  * @param graph - The coverage knowledge graph (from AST stage)
54
59
  * @param testFiles - List of test file paths
60
+ * @param fileContents - Optional test file contents keyed by file path. When absent,
61
+ * the mapper falls back to graph node metadata and finally to the filesystem.
55
62
  */
56
- function mapTestsToEndpoints(graph, testFiles) {
57
- var _a, _b;
63
+ function mapTestsToEndpoints(graph, testFiles, fileContents = {}) {
64
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
58
65
  const mappings = [];
59
- // Get all endpoint nodes
60
66
  const endpointNodes = graph.getNodesByType('endpoint');
61
- if (endpointNodes.length === 0)
62
- return mappings;
67
+ const seen = new Set();
63
68
  for (const testFile of testFiles) {
64
69
  const fileNodeId = `file:${testFile}`;
65
- // 1. Check for existing 'tests' edges from AST stage
70
+ const content = resolveTestContent(graph, testFile, fileContents);
71
+ const insights = analyzeTestFile(graph, testFile, content);
72
+ const pushMapping = (mapping) => {
73
+ var _a, _b, _c, _d;
74
+ const key = [
75
+ mapping.testFilePath,
76
+ (_a = mapping.endpointId) !== null && _a !== void 0 ? _a : '',
77
+ (_b = mapping.serviceId) !== null && _b !== void 0 ? _b : '',
78
+ (_c = mapping.coveredMethod) !== null && _c !== void 0 ? _c : '',
79
+ (_d = mapping.businessRule) !== null && _d !== void 0 ? _d : '',
80
+ mapping.evidenceType,
81
+ ].join('|');
82
+ if (seen.has(key))
83
+ return;
84
+ seen.add(key);
85
+ mappings.push({
86
+ ...mapping,
87
+ layer: insights.layer,
88
+ mockLibrary: insights.mockLibrary,
89
+ qualityScore: insights.qualityScore,
90
+ parameterizedExpansions: insights.parameterizedExpansions,
91
+ assertionCount: insights.assertionCount,
92
+ });
93
+ };
66
94
  if (graph.hasNode(fileNodeId)) {
67
95
  const testEdges = graph.getEdgesFrom(fileNodeId).filter((e) => e.type === 'tests');
68
96
  for (const edge of testEdges) {
69
- mappings.push({
97
+ const endpointNode = graph.getNode(edge.targetNodeId);
98
+ pushMapping({
70
99
  testFilePath: testFile,
71
100
  endpointId: edge.targetNodeId,
72
101
  evidenceType: 'explicit-url',
73
102
  confidence: 'high',
103
+ coversEndpoint: (_a = endpointNode === null || endpointNode === void 0 ? void 0 : endpointNode.label) !== null && _a !== void 0 ? _a : edge.targetNodeId,
104
+ businessRule: insights.businessRules[0],
105
+ serviceId: (_b = insights.coveredMethods[0]) === null || _b === void 0 ? void 0 : _b.serviceId,
106
+ coveredMethod: (_c = insights.coveredMethods[0]) === null || _c === void 0 ? void 0 : _c.qualifiedMethod,
74
107
  });
75
108
  }
76
109
  }
77
- // 2. Check for 'asserts' edges (higher confidence than just 'tests')
78
110
  if (graph.hasNode(fileNodeId)) {
79
111
  const assertEdges = graph.getEdgesFrom(fileNodeId).filter((e) => e.type === 'asserts');
80
112
  for (const edge of assertEdges) {
81
- // Don't duplicate if already mapped via 'tests'
82
- if (!mappings.some((m) => m.testFilePath === testFile && m.endpointId === edge.targetNodeId)) {
83
- mappings.push({
84
- testFilePath: testFile,
85
- endpointId: edge.targetNodeId,
86
- evidenceType: 'explicit-url',
87
- confidence: 'high',
88
- });
89
- }
113
+ const endpointNode = graph.getNode(edge.targetNodeId);
114
+ pushMapping({
115
+ testFilePath: testFile,
116
+ endpointId: edge.targetNodeId,
117
+ evidenceType: 'explicit-url',
118
+ confidence: 'high',
119
+ coversEndpoint: (_d = endpointNode === null || endpointNode === void 0 ? void 0 : endpointNode.label) !== null && _d !== void 0 ? _d : edge.targetNodeId,
120
+ businessRule: insights.businessRules[0],
121
+ serviceId: (_e = insights.coveredMethods[0]) === null || _e === void 0 ? void 0 : _e.serviceId,
122
+ coveredMethod: (_f = insights.coveredMethods[0]) === null || _f === void 0 ? void 0 : _f.qualifiedMethod,
123
+ });
90
124
  }
91
125
  }
92
- // 3. Naming convention matching
93
126
  const testBasename = path.basename(testFile, path.extname(testFile))
94
127
  .replace(/\.(test|spec|Test|Tests|Spec|IT)$/, '')
95
128
  .replace(/^test_|_test$/, '')
96
129
  .replace(/^Test|Test$/, '');
97
130
  for (const endpoint of endpointNodes) {
98
- const handlerName = (_b = (_a = endpoint.metadata) === null || _a === void 0 ? void 0 : _a.handlerFunction) !== null && _b !== void 0 ? _b : '';
99
- const endpointLabel = endpoint.label.toLowerCase();
100
- // Match test file name to handler/controller name
101
- if (testBasename.toLowerCase().includes(handlerName.toLowerCase()) && handlerName.length > 3) {
102
- if (!mappings.some((m) => m.testFilePath === testFile && m.endpointId === endpoint.id)) {
103
- mappings.push({
104
- testFilePath: testFile,
105
- endpointId: endpoint.id,
106
- evidenceType: 'naming-convention',
107
- confidence: 'low',
108
- });
109
- }
131
+ const handlerName = String((_h = (_g = endpoint.metadata) === null || _g === void 0 ? void 0 : _g.handlerFunction) !== null && _h !== void 0 ? _h : '');
132
+ if (handlerName.length > 3 &&
133
+ testBasename.toLowerCase().includes(handlerName.toLowerCase())) {
134
+ pushMapping({
135
+ testFilePath: testFile,
136
+ endpointId: endpoint.id,
137
+ evidenceType: 'naming-convention',
138
+ confidence: 'low',
139
+ coversEndpoint: endpoint.label,
140
+ businessRule: insights.businessRules[0],
141
+ serviceId: (_j = insights.coveredMethods[0]) === null || _j === void 0 ? void 0 : _j.serviceId,
142
+ coveredMethod: (_k = insights.coveredMethods[0]) === null || _k === void 0 ? void 0 : _k.qualifiedMethod,
143
+ });
110
144
  }
111
145
  }
112
- // 4. Import graph traversal: follow imports from test file to find endpoint connections
113
146
  if (graph.hasNode(fileNodeId)) {
114
147
  const importEdges = graph.getEdgesFrom(fileNodeId).filter((e) => e.type === 'imports-helper');
115
148
  for (const importEdge of importEdges) {
116
- // Check if the imported file defines any endpoints
117
- const importedFileEdges = graph.getEdgesFrom(importEdge.targetNodeId);
118
- for (const fileEdge of importedFileEdges) {
149
+ for (const fileEdge of graph.getEdgesFrom(importEdge.targetNodeId)) {
119
150
  if (fileEdge.type === 'tests' || fileEdge.type === 'defines') {
120
- if (!mappings.some((m) => m.testFilePath === testFile && m.endpointId === fileEdge.targetNodeId)) {
121
- mappings.push({
122
- testFilePath: testFile,
123
- endpointId: fileEdge.targetNodeId,
124
- evidenceType: 'import-graph',
125
- confidence: 'medium',
126
- });
127
- }
151
+ const endpointNode = graph.getNode(fileEdge.targetNodeId);
152
+ pushMapping({
153
+ testFilePath: testFile,
154
+ endpointId: fileEdge.targetNodeId,
155
+ evidenceType: 'import-graph',
156
+ confidence: 'medium',
157
+ coversEndpoint: (_l = endpointNode === null || endpointNode === void 0 ? void 0 : endpointNode.label) !== null && _l !== void 0 ? _l : fileEdge.targetNodeId,
158
+ businessRule: insights.businessRules[0],
159
+ serviceId: (_m = insights.coveredMethods[0]) === null || _m === void 0 ? void 0 : _m.serviceId,
160
+ coveredMethod: (_o = insights.coveredMethods[0]) === null || _o === void 0 ? void 0 : _o.qualifiedMethod,
161
+ });
128
162
  }
129
163
  }
130
164
  }
131
165
  }
166
+ for (const coveredMethod of insights.coveredMethods) {
167
+ const endpoints = resolveEndpointsForMethod(graph, coveredMethod);
168
+ if (endpoints.length > 0) {
169
+ for (const endpoint of endpoints) {
170
+ pushMapping({
171
+ testFilePath: testFile,
172
+ endpointId: endpoint.id,
173
+ evidenceType: 'service-call',
174
+ confidence: 'medium',
175
+ serviceId: coveredMethod.serviceId,
176
+ coveredMethod: coveredMethod.qualifiedMethod,
177
+ businessRule: insights.businessRules[0],
178
+ coversEndpoint: endpoint.label,
179
+ });
180
+ }
181
+ }
182
+ else {
183
+ pushMapping({
184
+ testFilePath: testFile,
185
+ evidenceType: 'service-call',
186
+ confidence: 'medium',
187
+ serviceId: coveredMethod.serviceId,
188
+ coveredMethod: coveredMethod.qualifiedMethod,
189
+ businessRule: insights.businessRules[0],
190
+ });
191
+ }
192
+ }
193
+ for (const businessRule of insights.businessRules) {
194
+ pushMapping({
195
+ testFilePath: testFile,
196
+ evidenceType: 'business-rule',
197
+ confidence: insights.coveredMethods.length > 0 ? 'medium' : 'low',
198
+ serviceId: (_p = insights.coveredMethods[0]) === null || _p === void 0 ? void 0 : _p.serviceId,
199
+ coveredMethod: (_q = insights.coveredMethods[0]) === null || _q === void 0 ? void 0 : _q.qualifiedMethod,
200
+ businessRule,
201
+ coversEndpoint: (_r = mappings.find((m) => m.testFilePath === testFile)) === null || _r === void 0 ? void 0 : _r.coversEndpoint,
202
+ });
203
+ }
132
204
  }
133
205
  return mappings;
134
206
  }
207
+ function resolveTestContent(graph, testFile, fileContents) {
208
+ var _a;
209
+ if (typeof fileContents[testFile] === 'string') {
210
+ return fileContents[testFile];
211
+ }
212
+ const fileNode = graph.getNode(`file:${testFile}`);
213
+ if (typeof ((_a = fileNode === null || fileNode === void 0 ? void 0 : fileNode.metadata) === null || _a === void 0 ? void 0 : _a.content) === 'string') {
214
+ return fileNode.metadata.content;
215
+ }
216
+ try {
217
+ if (fs.existsSync(testFile)) {
218
+ return fs.readFileSync(testFile, 'utf-8');
219
+ }
220
+ }
221
+ catch {
222
+ return '';
223
+ }
224
+ return '';
225
+ }
226
+ function analyzeTestFile(graph, testFile, content) {
227
+ const language = detectLanguageFromPath(testFile);
228
+ const expandedTests = (0, parameterizedTestExpander_1.expandParameterizedTests)(testFile, content, language);
229
+ const injectedTargets = extractInjectedTargets(content);
230
+ const coveredMethods = extractCoveredMethods(content, injectedTargets);
231
+ const layer = (0, testLayerClassifier_1.classifyTestLayer)(testFile, content).layer;
232
+ return {
233
+ layer,
234
+ mockLibrary: detectMockLibrary(content),
235
+ qualityScore: scoreUnitTestFile(content),
236
+ parameterizedExpansions: expandedTests.reduce((sum, test) => typeof test.variantCount === 'number' ? sum + test.variantCount : sum, 0),
237
+ assertionCount: countAssertions(content, graph, testFile),
238
+ injectedTargets,
239
+ coveredMethods,
240
+ businessRules: extractBusinessRules(content),
241
+ };
242
+ }
243
+ function detectLanguageFromPath(filePath) {
244
+ const ext = path.extname(filePath).toLowerCase();
245
+ if (ext === '.java')
246
+ return 'java';
247
+ if (ext === '.kt' || ext === '.kts')
248
+ return 'kotlin';
249
+ if (ext === '.py')
250
+ return 'python';
251
+ if (ext === '.ts' || ext === '.tsx')
252
+ return 'typescript';
253
+ return 'javascript';
254
+ }
255
+ function extractInjectedTargets(content) {
256
+ const targets = [];
257
+ const regex = /@InjectMocks[\s\S]{0,1000}?(?:private|protected|public|internal)?\s*([A-Z]\w*)\s+([a-zA-Z_]\w*)\s*(?:=|;)/g;
258
+ let match;
259
+ while ((match = regex.exec(content)) !== null) {
260
+ targets.push({ className: match[1], variableName: match[2] });
261
+ }
262
+ const kotlinRegex = /@InjectMocks[\s\S]{0,1000}?(?:private|protected|public|internal)?\s*(?:lateinit\s+)?var\s+([a-zA-Z_]\w*)\s*:\s*([A-Z]\w*)/g;
263
+ while ((match = kotlinRegex.exec(content)) !== null) {
264
+ targets.push({ className: match[2], variableName: match[1] });
265
+ }
266
+ return dedupeBy(targets, (target) => `${target.className}:${target.variableName}`);
267
+ }
268
+ function extractCoveredMethods(content, injectedTargets) {
269
+ const methods = [];
270
+ for (const target of injectedTargets) {
271
+ const callRegex = new RegExp(`${target.variableName}\\.([a-zA-Z_]\\w*)\\s*\\(`, 'g');
272
+ let match;
273
+ while ((match = callRegex.exec(content)) !== null) {
274
+ methods.push({
275
+ serviceId: target.className,
276
+ methodName: match[1],
277
+ qualifiedMethod: `${target.className}.${match[1]}`,
278
+ });
279
+ }
280
+ }
281
+ return dedupeBy(methods, (method) => method.qualifiedMethod);
282
+ }
283
+ function extractBusinessRules(content) {
284
+ const names = [];
285
+ const testNameRegexes = [
286
+ /@Test[\s\S]{0,120}?(?:void|fun)\s+(\w+)\s*\(/g,
287
+ /@ParameterizedTest[\s\S]{0,120}?(?:void|fun)\s+(\w+)\s*\(/g,
288
+ /@DisplayName\(\s*["'`]([^"'`]+)["'`]\s*\)/g,
289
+ ];
290
+ for (const regex of testNameRegexes) {
291
+ let match;
292
+ while ((match = regex.exec(content)) !== null) {
293
+ const normalized = normalizeBusinessRule(match[1]);
294
+ if (normalized) {
295
+ names.push(normalized);
296
+ }
297
+ }
298
+ }
299
+ return dedupeBy(names, (name) => name);
300
+ }
301
+ function normalizeBusinessRule(rawName) {
302
+ const words = rawName
303
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
304
+ .replace(/[_-]+/g, ' ')
305
+ .toLowerCase()
306
+ .split(/\s+/)
307
+ .filter(Boolean)
308
+ .filter((word) => ![
309
+ 'should',
310
+ 'test',
311
+ 'successfully',
312
+ 'when',
313
+ 'then',
314
+ 'given',
315
+ 'throws',
316
+ 'throw',
317
+ 'exception',
318
+ 'returns',
319
+ 'return',
320
+ 'with',
321
+ 'method',
322
+ 'case',
323
+ ].includes(word));
324
+ if (words.length === 0)
325
+ return undefined;
326
+ return words.slice(0, 4).join(' ');
327
+ }
328
+ function detectMockLibrary(content) {
329
+ if (/@Mock\b|Mockito\.|@InjectMocks\b|@ExtendWith\(MockitoExtension/i.test(content)) {
330
+ return 'mockito';
331
+ }
332
+ if (/mockk|every\s*\{|verify\s*\{|\.should\(\)\.have\./i.test(content)) {
333
+ return 'mockk';
334
+ }
335
+ if (/jest\.mock|jest\.spyOn/.test(content)) {
336
+ return 'jest';
337
+ }
338
+ if (/mocker\.|unittest\.mock|pytest-mock/.test(content)) {
339
+ return 'pytest-mock';
340
+ }
341
+ return undefined;
342
+ }
343
+ function countAssertions(graphContent, graph, testFile) {
344
+ var _a, _b, _c;
345
+ const matches = graphContent.match(/assertThat\s*\(|assertEquals\s*\(|assertNotNull\s*\(|assertTrue\s*\(|assertFalse\s*\(|assertThrows\s*\(|expect\s*\(|Mockito\.verify\s*\(|verify\s*\(/g);
346
+ const contentCount = (_a = matches === null || matches === void 0 ? void 0 : matches.length) !== null && _a !== void 0 ? _a : 0;
347
+ const assertionNode = graph.getNode(`assertion:${testFile}`);
348
+ const graphCount = Number((_c = (_b = assertionNode === null || assertionNode === void 0 ? void 0 : assertionNode.metadata) === null || _b === void 0 ? void 0 : _b.assertionCount) !== null && _c !== void 0 ? _c : 0);
349
+ return Math.max(contentCount, graphCount);
350
+ }
351
+ function scoreUnitTestFile(content) {
352
+ let score = 0;
353
+ const hasSpecificAssertions = /assertThat\s*\(|assertEquals\s*\(|expect\([^)]*\)\.(?:toEqual|toBe|toContain|toStrictEqual)/.test(content);
354
+ const hasFluentAssertions = /assertThat\s*\([\s\S]*?\)\.is|\.should\(\)\.have\./i.test(content);
355
+ const hasWeakAssertions = /assertTrue\s*\(|assertNotNull\s*\(/.test(content);
356
+ const hasAnyAssertion = hasSpecificAssertions || hasFluentAssertions || hasWeakAssertions || /assertThrows\s*\(/.test(content);
357
+ if (hasSpecificAssertions)
358
+ score += 25;
359
+ else if (hasFluentAssertions)
360
+ score += 15;
361
+ else if (!hasAnyAssertion)
362
+ score -= 10;
363
+ const hasInjectMocks = /@InjectMocks\b/.test(content);
364
+ const hasMocks = /@Mock\b|mockk|jest\.mock|mocker\.|spyOn/.test(content);
365
+ const hasVerify = /Mockito\.verify\s*\(|verify\s*\(|\.should\(\)\.have\./.test(content);
366
+ const mocksClassUnderTest = /@Mock[\s\S]{0,80}?([A-Z]\w*Service|[A-Z]\w*Controller)\s+[a-zA-Z_]\w*/.test(content) && !hasInjectMocks;
367
+ const usesRealExternalCalls = /new\s+RestTemplate|WebClient\.builder|axios\.|fetch\s*\(|httpClient\./.test(content);
368
+ if (hasInjectMocks && hasMocks)
369
+ score += 25;
370
+ else if (hasVerify)
371
+ score += 15;
372
+ else if (mocksClassUnderTest)
373
+ score -= 10;
374
+ else if (!hasMocks && usesRealExternalCalls)
375
+ score -= 15;
376
+ const descriptiveName = /(?:void|fun)\s+should[A-Z]\w+When[A-Z]\w+\s*\(/.test(content)
377
+ || /(?:void|fun)\s+should[A-Z]\w{10,}\s*\(/.test(content);
378
+ const hasDisplayName = /@DisplayName\(\s*["'`][^"'`]{10,}["'`]\s*\)/.test(content);
379
+ if (descriptiveName)
380
+ score += 20;
381
+ else if (hasDisplayName)
382
+ score += 10;
383
+ const coversEdgeCases = /\bnull\b|\bempty\b|\bboundary\b|\bmax\b|\bmin\b|\bzero\b|\bblank\b|\bnegative\b/i.test(content);
384
+ const coversErrorPath = /assertThrows|exception|invalid|notFound|failure|error/i.test(content);
385
+ if (coversEdgeCases)
386
+ score += 20;
387
+ else if (coversErrorPath)
388
+ score += 10;
389
+ if (!/@SpringBootTest\b/.test(content))
390
+ score += 10;
391
+ else if (/@MockBean\b/.test(content))
392
+ score += 5;
393
+ else
394
+ score -= 10;
395
+ return Math.max(0, Math.min(100, score));
396
+ }
397
+ function resolveEndpointsForMethod(graph, coveredMethod) {
398
+ const queue = findMethodNodeIds(graph, coveredMethod);
399
+ const visited = new Set();
400
+ const endpoints = new Map();
401
+ while (queue.length > 0) {
402
+ const currentId = queue.shift();
403
+ if (!currentId)
404
+ continue;
405
+ if (visited.has(currentId))
406
+ continue;
407
+ visited.add(currentId);
408
+ for (const edge of graph.getEdgesFrom(currentId)) {
409
+ if (edge.type === 'defines') {
410
+ const endpoint = graph.getNode(edge.targetNodeId);
411
+ if ((endpoint === null || endpoint === void 0 ? void 0 : endpoint.type) === 'endpoint') {
412
+ endpoints.set(endpoint.id, endpoint);
413
+ }
414
+ }
415
+ }
416
+ for (const incomingEdge of graph.getEdgesTo(currentId)) {
417
+ if (incomingEdge.type === 'calls' && !visited.has(incomingEdge.sourceNodeId)) {
418
+ queue.push(incomingEdge.sourceNodeId);
419
+ }
420
+ }
421
+ }
422
+ return Array.from(endpoints.values());
423
+ }
424
+ function findMethodNodeIds(graph, coveredMethod) {
425
+ const allNodes = graph.getAllNodes();
426
+ return allNodes
427
+ .filter((node) => node.type === 'function' || node.type === 'service' || node.type === 'class')
428
+ .filter((node) => {
429
+ const label = node.label.toLowerCase();
430
+ const id = node.id.toLowerCase();
431
+ return (label === coveredMethod.methodName.toLowerCase()
432
+ || id.includes(coveredMethod.qualifiedMethod.toLowerCase())
433
+ || id.includes(`${coveredMethod.serviceId.toLowerCase()}:${coveredMethod.methodName.toLowerCase()}`));
434
+ })
435
+ .map((node) => node.id);
436
+ }
437
+ function dedupeBy(items, keySelector) {
438
+ const seen = new Set();
439
+ const deduped = [];
440
+ for (const item of items) {
441
+ const key = keySelector(item);
442
+ if (seen.has(key))
443
+ continue;
444
+ seen.add(key);
445
+ deduped.push(item);
446
+ }
447
+ return deduped;
448
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"testLayerClassifier.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/tia/testLayerClassifier.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AA8GlD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,kBAAkB,CA0DpB"}
1
+ {"version":3,"file":"testLayerClassifier.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/tia/testLayerClassifier.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AA6HlD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,kBAAkB,CA0DpB"}
@@ -58,12 +58,16 @@ const CLASSIFICATION_RULES = [
58
58
  },
59
59
  {
60
60
  layer: 'performance',
61
- directoryPatterns: [/\bperformance\b/i, /\bperf\b/i, /\bload\b/i, /\bstress\b/i, /\bbenchmark\b/i],
62
- fileNamePatterns: [/\.perf\./i, /\.bench\./i, /\.load\./i, /\.k6\./i],
61
+ directoryPatterns: [/\bperformance\b/i, /\bperformance-tests\b/i, /\bperf\b/i, /\bload\b/i, /\bstress\b/i, /\bbenchmark\b/i],
62
+ fileNamePatterns: [/\.perf\./i, /\.bench\./i, /\.load\./i, /\.k6\./i, /Simulation\.(java|kt)$/i],
63
63
  contentPatterns: [
64
64
  /import\s.*k6/, // k6
65
65
  /from\s+['"]k6/,
66
66
  /io\.gatling/i, // Gatling
67
+ /extends\s+Simulation\b/, // Gatling Java/Kotlin Simulation
68
+ /ScenarioBuilder|setUp\s*\(/, // Gatling scenario setup
69
+ /http\s*\([^)]*\)\s*\.\s*(?:get|post|put|delete)\s*\(/, // Gatling HTTP requests
70
+ /rampUsers\s*\(|constantUsersPerSec\s*\(|atOnceUsers\s*\(/, // Gatling load profiles
67
71
  /locust|HttpUser|TaskSet/i, // Locust
68
72
  /import\s.*artillery/i, // Artillery
69
73
  /autocannon/i, // Autocannon
@@ -99,14 +103,18 @@ const CLASSIFICATION_RULES = [
99
103
  },
100
104
  {
101
105
  layer: 'integration',
102
- directoryPatterns: [/\bintegration\b/i, /\bint[-_]?test\b/i],
103
- fileNamePatterns: [/\.integration\./i, /\.int\./i, /IT\.java$/],
106
+ directoryPatterns: [/\bintegration\b/i, /\bintegration-tests\b/i, /\bcontract-tests\b/i, /\bint[-_]?test\b/i],
107
+ fileNamePatterns: [/\.integration\./i, /\.int\./i, /IT\.(java|kt)$/i, /IntegrationTest\.(java|kt)$/i],
104
108
  contentPatterns: [
105
109
  /@SpringBootTest/, // Spring Boot integration test
110
+ /@AutoConfigureMockMvc/, // Spring MockMvc integration
106
111
  /TestRestTemplate/, // Spring REST testing
112
+ /@RestClientTest/, // Spring REST client slice
107
113
  /@Testcontainers/i, // Testcontainers
114
+ /@Container\b/, // Testcontainers field
108
115
  /@DataJpaTest/i, // Spring Data JPA
109
116
  /@WebMvcTest/i, // Spring MVC test
117
+ /extends\s+AbstractIntegrationTest\b/, // Convention-based integration base class
110
118
  /testcontainers/i, // Docker containers
111
119
  /@pytest\.fixture.*scope\s*=\s*['"]session['"]/, // pytest session-scoped fixture (DB lifecycle)
112
120
  /factory\.(?:Factory|DjangoModelFactory|SQLAlchemyModelFactory)/, // Factory Boy (real-model tests)
@@ -131,7 +139,14 @@ const CLASSIFICATION_RULES = [
131
139
  directoryPatterns: [/\bunit\b/i],
132
140
  fileNamePatterns: [/\.unit\./i],
133
141
  contentPatterns: [
134
- // Unit tests are the default; no specific content patterns needed
142
+ /@ExtendWith\(MockitoExtension/i,
143
+ /@RunWith\(MockitoJUnitRunner/i,
144
+ /@InjectMocks\b/,
145
+ /Mockito\.verify\s*\(/,
146
+ /assertThat\([\s\S]*?\)\.is/i,
147
+ /assertEquals|assertNotNull|assertTrue/,
148
+ /given\([\s\S]*?\)\.willReturn/i,
149
+ /\.should\(\)\.have\./,
135
150
  ],
136
151
  priority: 10,
137
152
  },
@@ -1 +1 @@
1
- {"version":3,"file":"tiaStage.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/tia/tiaStage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE3E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAWzC,qBAAa,QAAS,YAAW,aAAa,CAAC,SAAS,CAAC;IACvD,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAC/B,QAAQ,CAAC,QAAQ,SAAS;IAEpB,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;CAmJ5D"}
1
+ {"version":3,"file":"tiaStage.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/tia/tiaStage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE3E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAWzC,qBAAa,QAAS,YAAW,aAAa,CAAC,SAAS,CAAC;IACvD,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAC/B,QAAQ,CAAC,QAAQ,SAAS;IAEpB,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;CAqJ5D"}
@@ -81,6 +81,7 @@ class TiaStage {
81
81
  parameterizedTests: [],
82
82
  testEndpointMappings: [],
83
83
  };
84
+ const testFileContents = {};
84
85
  // 1. Classify test layers
85
86
  for (const testFile of testFiles) {
86
87
  let content;
@@ -92,6 +93,7 @@ class TiaStage {
92
93
  continue;
93
94
  }
94
95
  filesScanned.push(testFile);
96
+ testFileContents[testFile] = content;
95
97
  const classification = (0, testLayerClassifier_1.classifyTestLayer)(testFile, content);
96
98
  output.classifications.push(classification);
97
99
  // 2. Detect mock boundaries
@@ -103,7 +105,7 @@ class TiaStage {
103
105
  output.parameterizedTests.push(...paramTests);
104
106
  }
105
107
  // 4. Map tests to endpoints
106
- output.testEndpointMappings = (0, testEndpointMapper_1.mapTestsToEndpoints)(context.graph, testFiles);
108
+ output.testEndpointMappings = (0, testEndpointMapper_1.mapTestsToEndpoints)(context.graph, testFiles, testFileContents);
107
109
  // 5. Populate graph with TIA-discovered nodes
108
110
  // Add mock-boundary nodes
109
111
  for (const boundary of output.mockBoundaries) {
@@ -36,9 +36,18 @@ export interface ExpandedParameterizedTest {
36
36
  */
37
37
  export interface TestEndpointMapping {
38
38
  testFilePath: string;
39
- endpointId: string;
40
- evidenceType: 'explicit-url' | 'resolved-constant' | 'import-graph' | 'naming-convention' | 'framework-metadata' | 'helper-traversal' | 'page-object';
39
+ endpointId?: string;
40
+ evidenceType: 'explicit-url' | 'resolved-constant' | 'import-graph' | 'naming-convention' | 'framework-metadata' | 'helper-traversal' | 'page-object' | 'service-call' | 'business-rule';
41
41
  confidence: 'high' | 'medium' | 'low';
42
+ serviceId?: string;
43
+ businessRule?: string;
44
+ coveredMethod?: string;
45
+ layer?: string;
46
+ mockLibrary?: string;
47
+ qualityScore?: number;
48
+ parameterizedExpansions?: number;
49
+ assertionCount?: number;
50
+ coversEndpoint?: string;
42
51
  }
43
52
  /**
44
53
  * Output of the TIA pipeline stage.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/tia/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAA4B,MAAM,aAAa,CAAC;AAEjF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,cAAc,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,cAAc,GAAG,mBAAmB,GAAG,cAAc,GAAG,mBAAmB,GAAG,oBAAoB,GAAG,kBAAkB,GAAG,aAAa,CAAC;IACtJ,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;CACvC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,eAAe,EAAE,kBAAkB,EAAE,CAAC;IACtC,cAAc,EAAE,oBAAoB,EAAE,CAAC;IACvC,kBAAkB,EAAE,yBAAyB,EAAE,CAAC;IAChD,oBAAoB,EAAE,mBAAmB,EAAE,CAAC;CAC7C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/tia/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAA4B,MAAM,aAAa,CAAC;AAEjF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,cAAc,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EACR,cAAc,GACd,mBAAmB,GACnB,cAAc,GACd,mBAAmB,GACnB,oBAAoB,GACpB,kBAAkB,GAClB,aAAa,GACb,cAAc,GACd,eAAe,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,eAAe,EAAE,kBAAkB,EAAE,CAAC;IACtC,cAAc,EAAE,oBAAoB,EAAE,CAAC;IACvC,kBAAkB,EAAE,yBAAyB,EAAE,CAAC;IAChD,oBAAoB,EAAE,mBAAmB,EAAE,CAAC;CAC7C"}
@@ -0,0 +1,6 @@
1
+ export declare const DEFAULT_DISCOVERY_EXCLUDE_DIRS: readonly ["node_modules", ".git", "dist", "build", "target", ".cache", "coverage", ".nyc_output", "__pycache__", ".pytest_cache", ".tox", "vendor", ".bundle", ".gradle"];
2
+ export declare const DEFAULT_GENERATED_SOURCE_DIRS: readonly ["build/generated-sources", "target/generated-sources", "src/generated", "build/generated", "target/generated"];
3
+ export declare const DEFAULT_OPENAPI_INTERFACE_SUFFIXES: readonly ["Api", "ApiDelegate", "Controller", "Resource", "Endpoint"];
4
+ export declare const DEFAULT_OPENAPI_EXCLUDE_SUFFIXES: readonly ["Mapper", "Repository", "Dao", "Client", "Feign"];
5
+ export declare const DEFAULT_GENERATED_SOURCE_PATH_SEGMENTS: string[];
6
+ //# sourceMappingURL=projectDefaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectDefaults.d.ts","sourceRoot":"","sources":["../../src/projectDefaults.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,8BAA8B,2KAejC,CAAC;AAEX,eAAO,MAAM,6BAA6B,0HAMhC,CAAC;AAEX,eAAO,MAAM,kCAAkC,uEAMrC,CAAC;AAEX,eAAO,MAAM,gCAAgC,6DAMnC,CAAC;AAEX,eAAO,MAAM,sCAAsC,UAMlD,CAAC"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_GENERATED_SOURCE_PATH_SEGMENTS = exports.DEFAULT_OPENAPI_EXCLUDE_SUFFIXES = exports.DEFAULT_OPENAPI_INTERFACE_SUFFIXES = exports.DEFAULT_GENERATED_SOURCE_DIRS = exports.DEFAULT_DISCOVERY_EXCLUDE_DIRS = void 0;
4
+ exports.DEFAULT_DISCOVERY_EXCLUDE_DIRS = [
5
+ 'node_modules',
6
+ '.git',
7
+ 'dist',
8
+ 'build',
9
+ 'target',
10
+ '.cache',
11
+ 'coverage',
12
+ '.nyc_output',
13
+ '__pycache__',
14
+ '.pytest_cache',
15
+ '.tox',
16
+ 'vendor',
17
+ '.bundle',
18
+ '.gradle',
19
+ ];
20
+ exports.DEFAULT_GENERATED_SOURCE_DIRS = [
21
+ 'build/generated-sources',
22
+ 'target/generated-sources',
23
+ 'src/generated',
24
+ 'build/generated',
25
+ 'target/generated',
26
+ ];
27
+ exports.DEFAULT_OPENAPI_INTERFACE_SUFFIXES = [
28
+ 'Api',
29
+ 'ApiDelegate',
30
+ 'Controller',
31
+ 'Resource',
32
+ 'Endpoint',
33
+ ];
34
+ exports.DEFAULT_OPENAPI_EXCLUDE_SUFFIXES = [
35
+ 'Mapper',
36
+ 'Repository',
37
+ 'Dao',
38
+ 'Client',
39
+ 'Feign',
40
+ ];
41
+ exports.DEFAULT_GENERATED_SOURCE_PATH_SEGMENTS = Array.from(new Set(exports.DEFAULT_GENERATED_SOURCE_DIRS
42
+ .flatMap((dir) => dir.split('/'))
43
+ .filter((segment) => segment.includes('generated'))));