api-tests-coverage 1.0.15 → 1.0.17
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.
- package/dist/dashboard/dist/assets/_basePickBy-C2jmWITn.js +1 -0
- package/dist/dashboard/dist/assets/_baseUniq-DE6cyzJb.js +1 -0
- package/dist/dashboard/dist/assets/arc-B-Q4nGPT.js +1 -0
- package/dist/dashboard/dist/assets/architectureDiagram-VXUJARFQ-C_5dqWCI.js +36 -0
- package/dist/dashboard/dist/assets/blockDiagram-VD42YOAC-DbGIO6Kt.js +122 -0
- package/dist/dashboard/dist/assets/c4Diagram-YG6GDRKO-CAFpcejP.js +10 -0
- package/dist/dashboard/dist/assets/channel-Di9el3wE.js +1 -0
- package/dist/dashboard/dist/assets/chunk-4BX2VUAB-DY1boKsq.js +1 -0
- package/dist/dashboard/dist/assets/chunk-55IACEB6-BSL35gyW.js +1 -0
- package/dist/dashboard/dist/assets/chunk-B4BG7PRW-eTDXrKrv.js +165 -0
- package/dist/dashboard/dist/assets/chunk-DI55MBZ5-M-8I3jEy.js +220 -0
- package/dist/dashboard/dist/assets/chunk-FMBD7UC4-bSA0XiS0.js +15 -0
- package/dist/dashboard/dist/assets/chunk-QN33PNHL-BrOIYUBs.js +1 -0
- package/dist/dashboard/dist/assets/chunk-QZHKN3VN-CliaQGD4.js +1 -0
- package/dist/dashboard/dist/assets/chunk-TZMSLE5B-CyhcxGB1.js +1 -0
- package/dist/dashboard/dist/assets/classDiagram-2ON5EDUG-BkGN4Cpz.js +1 -0
- package/dist/dashboard/dist/assets/classDiagram-v2-WZHVMYZB-BkGN4Cpz.js +1 -0
- package/dist/dashboard/dist/assets/clone-Cvq8JuOb.js +1 -0
- package/dist/dashboard/dist/assets/cose-bilkent-S5V4N54A-BUkL7Wtq.js +1 -0
- package/dist/dashboard/dist/assets/dagre-6UL2VRFP-B8oEROJc.js +4 -0
- package/dist/dashboard/dist/assets/diagram-PSM6KHXK-5uki9Dw8.js +24 -0
- package/dist/dashboard/dist/assets/diagram-QEK2KX5R-BRNhmby2.js +43 -0
- package/dist/dashboard/dist/assets/diagram-S2PKOQOG-D-ku_X8U.js +24 -0
- package/dist/dashboard/dist/assets/erDiagram-Q2GNP2WA-DGl6gPe2.js +60 -0
- package/dist/dashboard/dist/assets/flowDiagram-NV44I4VS-Co89qYBD.js +162 -0
- package/dist/dashboard/dist/assets/ganttDiagram-JELNMOA3-2r3WpWQC.js +267 -0
- package/dist/dashboard/dist/assets/gitGraphDiagram-V2S2FVAM-CuJ5l3TK.js +65 -0
- package/dist/dashboard/dist/assets/graph-ZtgwAPQj.js +1 -0
- package/dist/dashboard/dist/assets/index-D3sRJga7.js +777 -0
- package/dist/dashboard/dist/assets/infoDiagram-HS3SLOUP-ujnMqVz3.js +2 -0
- package/dist/dashboard/dist/assets/journeyDiagram-XKPGCS4Q-DQzfeBIo.js +139 -0
- package/dist/dashboard/dist/assets/kanban-definition-3W4ZIXB7-ueIaoeks.js +89 -0
- package/dist/dashboard/dist/assets/layout-B1fTYUMj.js +1 -0
- package/dist/dashboard/dist/assets/mindmap-definition-VGOIOE7T-B7wYeLe1.js +68 -0
- package/dist/dashboard/dist/assets/pieDiagram-ADFJNKIX-Bf8vKEOf.js +30 -0
- package/dist/dashboard/dist/assets/quadrantDiagram-AYHSOK5B-CM8qiFLR.js +7 -0
- package/dist/dashboard/dist/assets/requirementDiagram-UZGBJVZJ-DPTtP4Ve.js +64 -0
- package/dist/dashboard/dist/assets/sankeyDiagram-TZEHDZUN-DEVTdH0h.js +10 -0
- package/dist/dashboard/dist/assets/sequenceDiagram-WL72ISMW-Bjr5wgXg.js +145 -0
- package/dist/dashboard/dist/assets/stateDiagram-FKZM4ZOC-DDrhZYly.js +1 -0
- package/dist/dashboard/dist/assets/stateDiagram-v2-4FDKWEC3-Im6pH8C-.js +1 -0
- package/dist/dashboard/dist/assets/timeline-definition-IT6M3QCI-DAT3r9va.js +61 -0
- package/dist/dashboard/dist/assets/treemap-GDKQZRPO-BlA8rg0m.js +162 -0
- package/dist/dashboard/dist/assets/xychartDiagram-PRI3JC2R-7aSkQtVu.js +7 -0
- package/dist/src/ast/astTypes.d.ts +86 -0
- package/dist/src/ast/astTypes.d.ts.map +1 -1
- package/dist/src/discovery/fileClassifier.d.ts.map +1 -1
- package/dist/src/discovery/fileClassifier.js +15 -16
- package/dist/src/discovery/frameworkDetector.d.ts +28 -0
- package/dist/src/discovery/frameworkDetector.d.ts.map +1 -0
- package/dist/src/discovery/frameworkDetector.js +189 -0
- package/dist/src/discovery/projectDiscovery.d.ts +5 -1
- package/dist/src/discovery/projectDiscovery.d.ts.map +1 -1
- package/dist/src/discovery/projectDiscovery.js +8 -1
- package/dist/src/inference/routeInference.d.ts.map +1 -1
- package/dist/src/inference/routeInference.js +224 -1
- package/dist/src/languages/java/graphqlSchemaParser.d.ts +65 -0
- package/dist/src/languages/java/graphqlSchemaParser.d.ts.map +1 -0
- package/dist/src/languages/java/graphqlSchemaParser.js +164 -0
- package/dist/src/languages/java/mybatisXmlParser.d.ts +52 -0
- package/dist/src/languages/java/mybatisXmlParser.d.ts.map +1 -0
- package/dist/src/languages/java/mybatisXmlParser.js +107 -0
- package/dist/src/languages/java/semanticBuilder.d.ts.map +1 -1
- package/dist/src/languages/java/semanticBuilder.js +69 -12
- package/dist/src/languages/javascript/angularDetector.d.ts +74 -0
- package/dist/src/languages/javascript/angularDetector.d.ts.map +1 -0
- package/dist/src/languages/javascript/angularDetector.js +227 -0
- package/dist/src/languages/javascript/assertionResolver.js +6 -4
- package/dist/src/languages/javascript/hapiDetector.d.ts +40 -0
- package/dist/src/languages/javascript/hapiDetector.d.ts.map +1 -0
- package/dist/src/languages/javascript/hapiDetector.js +174 -0
- package/dist/src/languages/javascript/mongooseDetector.d.ts +65 -0
- package/dist/src/languages/javascript/mongooseDetector.d.ts.map +1 -0
- package/dist/src/languages/javascript/mongooseDetector.js +237 -0
- package/dist/src/languages/javascript/vueDetector.d.ts +42 -0
- package/dist/src/languages/javascript/vueDetector.d.ts.map +1 -0
- package/dist/src/languages/javascript/vueDetector.js +109 -0
- package/dist/src/languages/python/index.d.ts +6 -2
- package/dist/src/languages/python/index.d.ts.map +1 -1
- package/dist/src/languages/python/index.js +200 -5
- package/dist/src/languages/python/testPatternDetector.d.ts +70 -0
- package/dist/src/languages/python/testPatternDetector.d.ts.map +1 -0
- package/dist/src/languages/python/testPatternDetector.js +201 -0
- package/dist/src/pipeline/confidence.d.ts +6 -1
- package/dist/src/pipeline/confidence.d.ts.map +1 -1
- package/dist/src/pipeline/confidence.js +8 -3
- package/dist/src/pipeline/graph.d.ts.map +1 -1
- package/dist/src/pipeline/graph.js +16 -4
- package/dist/src/pipeline/stages/ast/astStage.d.ts.map +1 -1
- package/dist/src/pipeline/stages/ast/astStage.js +51 -1
- package/dist/src/pipeline/stages/ast/baseUrlComposer.d.ts +44 -0
- package/dist/src/pipeline/stages/ast/baseUrlComposer.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/baseUrlComposer.js +97 -0
- package/dist/src/pipeline/stages/ast/crossFileResolutionPass.d.ts +54 -0
- package/dist/src/pipeline/stages/ast/crossFileResolutionPass.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/crossFileResolutionPass.js +88 -0
- package/dist/src/pipeline/stages/ast/crossFileResolver.d.ts.map +1 -1
- package/dist/src/pipeline/stages/ast/crossFileResolver.js +39 -1
- package/dist/src/pipeline/stages/ast/graphBuilder.d.ts.map +1 -1
- package/dist/src/pipeline/stages/ast/graphBuilder.js +81 -0
- package/dist/src/pipeline/stages/ast/optionalAuthUnifier.d.ts +41 -0
- package/dist/src/pipeline/stages/ast/optionalAuthUnifier.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/optionalAuthUnifier.js +101 -0
- package/dist/src/pipeline/stages/ast/resolvers/angularInjectionResolver.d.ts +18 -0
- package/dist/src/pipeline/stages/ast/resolvers/angularInjectionResolver.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/resolvers/angularInjectionResolver.js +96 -0
- package/dist/src/pipeline/stages/ast/resolvers/dddLayerResolver.d.ts +46 -0
- package/dist/src/pipeline/stages/ast/resolvers/dddLayerResolver.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/resolvers/dddLayerResolver.js +314 -0
- package/dist/src/pipeline/stages/ast/resolvers/expressRouterResolver.d.ts +17 -0
- package/dist/src/pipeline/stages/ast/resolvers/expressRouterResolver.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/resolvers/expressRouterResolver.js +65 -0
- package/dist/src/pipeline/stages/ast/resolvers/flaskBlueprintResolver.d.ts +17 -0
- package/dist/src/pipeline/stages/ast/resolvers/flaskBlueprintResolver.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/resolvers/flaskBlueprintResolver.js +114 -0
- package/dist/src/pipeline/stages/ast/resolvers/mybatisResolver.d.ts +27 -0
- package/dist/src/pipeline/stages/ast/resolvers/mybatisResolver.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/resolvers/mybatisResolver.js +130 -0
- package/dist/src/pipeline/stages/ast/resolvers/vuexActionResolver.d.ts +17 -0
- package/dist/src/pipeline/stages/ast/resolvers/vuexActionResolver.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/resolvers/vuexActionResolver.js +80 -0
- package/dist/src/pipeline/stages/ast/rulesEnforcer.d.ts +24 -0
- package/dist/src/pipeline/stages/ast/rulesEnforcer.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/rulesEnforcer.js +411 -0
- package/dist/src/pipeline/stages/ast/types.d.ts +114 -1
- package/dist/src/pipeline/stages/ast/types.d.ts.map +1 -1
- package/dist/src/pipeline/stages/merge/conflictDetector.d.ts +2 -0
- package/dist/src/pipeline/stages/merge/conflictDetector.d.ts.map +1 -1
- package/dist/src/pipeline/stages/merge/conflictDetector.js +54 -2
- package/dist/src/pipeline/stages/merge/coverageMappingBuilder.d.ts.map +1 -1
- package/dist/src/pipeline/stages/merge/coverageMappingBuilder.js +67 -3
- package/dist/src/pipeline/stages/tia/mockBoundaryDetector.d.ts.map +1 -1
- package/dist/src/pipeline/stages/tia/mockBoundaryDetector.js +8 -1
- package/dist/src/pipeline/stages/tia/parameterizedTestExpander.js +8 -4
- package/dist/src/pipeline/stages/tia/testLayerClassifier.d.ts.map +1 -1
- package/dist/src/pipeline/stages/tia/testLayerClassifier.js +41 -10
- package/dist/src/pipeline/types.d.ts +1 -1
- package/dist/src/pipeline/types.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -8,6 +8,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
8
8
|
exports.buildCoverageMappings = buildCoverageMappings;
|
|
9
9
|
const confidence_1 = require("../../confidence");
|
|
10
10
|
const mergeRules_1 = require("./mergeRules");
|
|
11
|
+
/** Rank test layers so deeper coverage layers win when comparing. */
|
|
12
|
+
const TEST_LAYER_RANK = {
|
|
13
|
+
e2e: 6,
|
|
14
|
+
api: 5,
|
|
15
|
+
integration: 4,
|
|
16
|
+
component: 3,
|
|
17
|
+
unit: 2,
|
|
18
|
+
security: 1,
|
|
19
|
+
performance: 1,
|
|
20
|
+
};
|
|
21
|
+
function testLayerRank(layer) {
|
|
22
|
+
var _a;
|
|
23
|
+
if (!layer)
|
|
24
|
+
return 0;
|
|
25
|
+
return (_a = TEST_LAYER_RANK[layer]) !== null && _a !== void 0 ? _a : 0;
|
|
26
|
+
}
|
|
11
27
|
/**
|
|
12
28
|
* Build coverage mappings for all endpoint-type nodes in the graph.
|
|
13
29
|
*/
|
|
@@ -59,9 +75,9 @@ function buildCoverageMappings(graph, tiaOutput, iastOutput, dastOutput, isStati
|
|
|
59
75
|
assertionConfirmed = true;
|
|
60
76
|
assertionSource = 'direct';
|
|
61
77
|
}
|
|
62
|
-
// Check test layer
|
|
78
|
+
// Check test layer — only replace if the new layer has a higher rank
|
|
63
79
|
const layer = testLayerLookup.get(testFilePath);
|
|
64
|
-
if (layer) {
|
|
80
|
+
if (layer && testLayerRank(layer) > testLayerRank(bestTestLayer)) {
|
|
65
81
|
bestTestLayer = layer;
|
|
66
82
|
}
|
|
67
83
|
// Check for mock boundaries on this test file
|
|
@@ -98,7 +114,7 @@ function buildCoverageMappings(graph, tiaOutput, iastOutput, dastOutput, isStati
|
|
|
98
114
|
const pathNodeIds = [endpoint.id, ...linkedTests.map((t) => `file:${t}`)];
|
|
99
115
|
const mockBoundaryOnPath = hasMockBoundary;
|
|
100
116
|
// Build confidence evidence
|
|
101
|
-
const evidence = (0, confidence_1.buildConfidenceEvidence)(graph, pathNodeIds, isStaticOnlyMode);
|
|
117
|
+
const evidence = (0, confidence_1.buildConfidenceEvidence)(graph, pathNodeIds, isStaticOnlyMode, iastConfirmed.has(endpoint.id), dastConfirmed.has(endpoint.id));
|
|
102
118
|
// Compute confidence
|
|
103
119
|
const confidence = (0, confidence_1.computeConfidence)(evidence);
|
|
104
120
|
// Determine coverage class
|
|
@@ -137,5 +153,53 @@ function buildCoverageMappings(graph, tiaOutput, iastOutput, dastOutput, isStati
|
|
|
137
153
|
traversalDepth,
|
|
138
154
|
});
|
|
139
155
|
}
|
|
156
|
+
// ─── Secondary mappings: service, error-branch, repository ────────────────
|
|
157
|
+
const secondaryNodeTypes = [
|
|
158
|
+
{ nodeType: 'service', itemType: 'service' },
|
|
159
|
+
{ nodeType: 'exception-branch', itemType: 'error-branch' },
|
|
160
|
+
{ nodeType: 'repository', itemType: 'repository' },
|
|
161
|
+
];
|
|
162
|
+
for (const { nodeType, itemType } of secondaryNodeTypes) {
|
|
163
|
+
const nodes = graph.getNodesByType(nodeType);
|
|
164
|
+
for (const node of nodes) {
|
|
165
|
+
const incomingEdges = graph.getEdgesTo(node.id);
|
|
166
|
+
const testEdges = incomingEdges.filter((e) => e.type === 'tests' || e.type === 'asserts');
|
|
167
|
+
const linkedTests = [];
|
|
168
|
+
const sourceStages = new Set([node.sourceStage]);
|
|
169
|
+
let assertionConfirmed = false;
|
|
170
|
+
let assertionSource = 'unresolved';
|
|
171
|
+
for (const edge of testEdges) {
|
|
172
|
+
const testFilePath = edge.sourceNodeId.replace(/^file:/, '');
|
|
173
|
+
if (!linkedTests.includes(testFilePath)) {
|
|
174
|
+
linkedTests.push(testFilePath);
|
|
175
|
+
}
|
|
176
|
+
sourceStages.add(edge.sourceStage);
|
|
177
|
+
if (edge.type === 'asserts') {
|
|
178
|
+
assertionConfirmed = true;
|
|
179
|
+
assertionSource = 'direct';
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const pathNodeIds = [node.id, ...linkedTests.map((t) => `file:${t}`)];
|
|
183
|
+
const evidence = (0, confidence_1.buildConfidenceEvidence)(graph, pathNodeIds, isStaticOnlyMode, false, false);
|
|
184
|
+
const confidence = (0, confidence_1.computeConfidence)(evidence);
|
|
185
|
+
const coverageClass = linkedTests.length > 0 ? 'unit-covered' : 'uncovered';
|
|
186
|
+
mappings.push({
|
|
187
|
+
itemId: node.id,
|
|
188
|
+
itemType,
|
|
189
|
+
linkedTests,
|
|
190
|
+
sourceStages: Array.from(sourceStages),
|
|
191
|
+
confidence,
|
|
192
|
+
coverageClass,
|
|
193
|
+
mockBoundaries: [],
|
|
194
|
+
assertionSource,
|
|
195
|
+
assertionConfirmed,
|
|
196
|
+
dastReachable: 'not-probed',
|
|
197
|
+
runtimeConfirmed: false,
|
|
198
|
+
urlResolution: 'unresolved',
|
|
199
|
+
conflicts: [],
|
|
200
|
+
traversalDepth: 0,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
140
204
|
return mappings;
|
|
141
205
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockBoundaryDetector.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/tia/mockBoundaryDetector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAmEpD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,oBAAoB,EAAE,
|
|
1
|
+
{"version":3,"file":"mockBoundaryDetector.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/tia/mockBoundaryDetector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAmEpD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,oBAAoB,EAAE,CAwDxB"}
|
|
@@ -102,7 +102,14 @@ function detectMockBoundaries(filePath, content, language) {
|
|
|
102
102
|
if (pattern.regex.test(line)) {
|
|
103
103
|
// Extract mocked target (heuristic: argument in parentheses)
|
|
104
104
|
const targetMatch = /[\(][\s]*['"`]?([a-zA-Z0-9_./@]+)['"`]?/.exec(line);
|
|
105
|
-
|
|
105
|
+
let mockedTarget = (_a = targetMatch === null || targetMatch === void 0 ? void 0 : targetMatch[1]) !== null && _a !== void 0 ? _a : 'unknown';
|
|
106
|
+
// Secondary extraction for Java/Kotlin annotation-style mocks (e.g. @Mock private UserService userService;)
|
|
107
|
+
if (mockedTarget === 'unknown') {
|
|
108
|
+
const annotationTypeMatch = line.match(/(?:private|protected|public)?\s*(\w+)\s+\w+\s*;/);
|
|
109
|
+
if (annotationTypeMatch) {
|
|
110
|
+
mockedTarget = annotationTypeMatch[1];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
106
113
|
boundaries.push({
|
|
107
114
|
testFilePath: filePath,
|
|
108
115
|
mockingLibrary: pattern.library,
|
|
@@ -102,9 +102,10 @@ function expandJavaKotlinParameterized(filePath, content) {
|
|
|
102
102
|
}
|
|
103
103
|
// ─── Jest Parameterized ─────────────────────────────────────────────────────
|
|
104
104
|
function expandJestParameterized(filePath, content) {
|
|
105
|
-
var _a;
|
|
105
|
+
var _a, _b;
|
|
106
106
|
const results = [];
|
|
107
107
|
const lines = content.split('\n');
|
|
108
|
+
let lineStartOffset = 0;
|
|
108
109
|
for (let i = 0; i < lines.length; i++) {
|
|
109
110
|
const line = lines[i];
|
|
110
111
|
// test.each([...])('name', ...)
|
|
@@ -113,11 +114,13 @@ function expandJestParameterized(filePath, content) {
|
|
|
113
114
|
const eachMatch = /(?:test|it|describe)\.each\s*\(\s*\[/.exec(line);
|
|
114
115
|
if (eachMatch) {
|
|
115
116
|
// Try to extract the array and count items
|
|
116
|
-
const
|
|
117
|
+
const matchOffset = lineStartOffset + ((_a = eachMatch.index) !== null && _a !== void 0 ? _a : 0);
|
|
118
|
+
const bracketStart = content.indexOf('[', matchOffset);
|
|
119
|
+
const arrayContent = extractBalancedBrackets(content, bracketStart);
|
|
117
120
|
const variantCount = arrayContent ? countArrayElements(arrayContent) : 'unresolvable';
|
|
118
121
|
// Extract test name from the next argument
|
|
119
|
-
const nameMatch = /\)\s*\(\s*['"`]([^'"`]+)['"`]/.exec(content.substring(
|
|
120
|
-
const testName = (
|
|
122
|
+
const nameMatch = /\)\s*\(\s*['"`]([^'"`]+)['"`]/.exec(content.substring(matchOffset));
|
|
123
|
+
const testName = (_b = nameMatch === null || nameMatch === void 0 ? void 0 : nameMatch[1]) !== null && _b !== void 0 ? _b : 'parameterized test';
|
|
121
124
|
results.push({
|
|
122
125
|
testFilePath: filePath,
|
|
123
126
|
testName,
|
|
@@ -146,6 +149,7 @@ function expandJestParameterized(filePath, content) {
|
|
|
146
149
|
line: i + 1,
|
|
147
150
|
});
|
|
148
151
|
}
|
|
152
|
+
lineStartOffset += lines[i].length + 1; // +1 for newline
|
|
149
153
|
}
|
|
150
154
|
return results;
|
|
151
155
|
}
|
|
@@ -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;
|
|
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,CAqFpB"}
|
|
@@ -92,6 +92,8 @@ const CLASSIFICATION_RULES = [
|
|
|
92
92
|
/httpx\.AsyncClient/i, // Python httpx
|
|
93
93
|
/RestAssured|given\(\)\./i, // REST Assured
|
|
94
94
|
/\.pact\./i, // Pact
|
|
95
|
+
/TestApp\s*\(/, // Python webtest TestApp
|
|
96
|
+
/\.\s*(?:post_json|put_json|delete_json|patch_json)\s*\(/, // webtest JSON methods
|
|
95
97
|
],
|
|
96
98
|
priority: 70,
|
|
97
99
|
},
|
|
@@ -106,6 +108,9 @@ const CLASSIFICATION_RULES = [
|
|
|
106
108
|
/@DataJpaTest/i, // Spring Data JPA
|
|
107
109
|
/@WebMvcTest/i, // Spring MVC test
|
|
108
110
|
/testcontainers/i, // Docker containers
|
|
111
|
+
/@pytest\.fixture.*scope\s*=\s*['"]session['"]/, // pytest session-scoped fixture (DB lifecycle)
|
|
112
|
+
/factory\.(?:Factory|DjangoModelFactory|SQLAlchemyModelFactory)/, // Factory Boy (real-model tests)
|
|
113
|
+
/create_engine|sessionmaker|Base\.metadata/, // SQLAlchemy DB setup
|
|
109
114
|
],
|
|
110
115
|
priority: 60,
|
|
111
116
|
},
|
|
@@ -143,12 +148,20 @@ function classifyTestLayer(filePath, content) {
|
|
|
143
148
|
const basename = path.basename(filePath);
|
|
144
149
|
// Sort rules by priority (highest first)
|
|
145
150
|
const sortedRules = [...CLASSIFICATION_RULES].sort((a, b) => b.priority - a.priority);
|
|
151
|
+
// Track the best path-only (directory/filename) candidate in case no
|
|
152
|
+
// content-based match is found. Content-based evidence always wins over
|
|
153
|
+
// path-based evidence so that a file living in /tests/integration/ but
|
|
154
|
+
// containing only unit-level code is classified by its content, not its
|
|
155
|
+
// directory name.
|
|
156
|
+
let pathOnlyCandidate = null;
|
|
146
157
|
for (const rule of sortedRules) {
|
|
147
158
|
let matchCount = 0;
|
|
159
|
+
let hasContentMatch = false;
|
|
160
|
+
const ruleSignals = [];
|
|
148
161
|
// Check directory patterns
|
|
149
162
|
for (const pattern of rule.directoryPatterns) {
|
|
150
163
|
if (pattern.test(normalizedPath)) {
|
|
151
|
-
|
|
164
|
+
ruleSignals.push(`dir:${rule.layer}`);
|
|
152
165
|
matchCount++;
|
|
153
166
|
break;
|
|
154
167
|
}
|
|
@@ -156,7 +169,7 @@ function classifyTestLayer(filePath, content) {
|
|
|
156
169
|
// Check file name patterns
|
|
157
170
|
for (const pattern of rule.fileNamePatterns) {
|
|
158
171
|
if (pattern.test(basename)) {
|
|
159
|
-
|
|
172
|
+
ruleSignals.push(`name:${rule.layer}`);
|
|
160
173
|
matchCount++;
|
|
161
174
|
break;
|
|
162
175
|
}
|
|
@@ -165,22 +178,40 @@ function classifyTestLayer(filePath, content) {
|
|
|
165
178
|
if (content) {
|
|
166
179
|
for (const pattern of rule.contentPatterns) {
|
|
167
180
|
if (pattern.test(content)) {
|
|
168
|
-
|
|
181
|
+
ruleSignals.push(`content:${rule.layer}`);
|
|
169
182
|
matchCount++;
|
|
183
|
+
hasContentMatch = true;
|
|
170
184
|
break;
|
|
171
185
|
}
|
|
172
186
|
}
|
|
173
187
|
}
|
|
174
188
|
if (matchCount > 0) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
189
|
+
if (hasContentMatch) {
|
|
190
|
+
// Content-based match — return immediately (highest-priority content wins)
|
|
191
|
+
signals.push(...ruleSignals);
|
|
192
|
+
const confidence = matchCount >= 2 ? 'high' : 'medium';
|
|
193
|
+
return {
|
|
194
|
+
filePath,
|
|
195
|
+
layer: rule.layer,
|
|
196
|
+
confidence,
|
|
197
|
+
signals,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
else if (!pathOnlyCandidate) {
|
|
201
|
+
// Path-only match — store as candidate but keep searching for content
|
|
202
|
+
pathOnlyCandidate = {
|
|
203
|
+
filePath,
|
|
204
|
+
layer: rule.layer,
|
|
205
|
+
confidence: matchCount >= 2 ? 'high' : 'medium',
|
|
206
|
+
signals: [...ruleSignals],
|
|
207
|
+
};
|
|
208
|
+
}
|
|
182
209
|
}
|
|
183
210
|
}
|
|
211
|
+
// If a path-only candidate was found but no content-based match, use it
|
|
212
|
+
if (pathOnlyCandidate) {
|
|
213
|
+
return pathOnlyCandidate;
|
|
214
|
+
}
|
|
184
215
|
// Default: unit test
|
|
185
216
|
return {
|
|
186
217
|
filePath,
|
|
@@ -24,7 +24,7 @@ export type UrlResolution = 'literal' | 'symbolic' | 'unresolved';
|
|
|
24
24
|
export type ConflictType = 'dast-unreachable' | 'runtime-unconfirmed' | 'stage-disagreement' | 'security-annotation-not-enforced' | 'unhandled-server-error' | 'undeclared-endpoint';
|
|
25
25
|
export type ConflictSeverity = 'info' | 'warning' | 'error';
|
|
26
26
|
export type GraphNodeType = 'endpoint' | 'parameter' | 'controller' | 'service' | 'repository' | 'model' | 'exception-branch' | 'route' | 'file' | 'class' | 'function' | 'test-file' | 'test-suite' | 'test-case' | 'assertion' | 'fixture' | 'helper' | 'base-test-class' | 'mock-boundary' | 'param-variant' | 'conflict' | 'runtime-event' | 'dependency';
|
|
27
|
-
export type GraphEdgeType = 'defines' | 'calls' | 'validates' | 'throws' | 'handles' | 'tests' | 'asserts' | 'extends' | 'imports-helper' | 'mocks' | 'resolves-to' | 'param-expands-to' | 'depends-on' | 'observed-by' | 'executes' | 'conflicts-with';
|
|
27
|
+
export type GraphEdgeType = 'defines' | 'calls' | 'validates' | 'throws' | 'handles' | 'tests' | 'asserts' | 'extends' | 'imports-helper' | 'mocks' | 'resolves-to' | 'param-expands-to' | 'depends-on' | 'observed-by' | 'executes' | 'conflicts-with' | 'router-mount' | 'injects' | 'implements';
|
|
28
28
|
export interface GraphNode {
|
|
29
29
|
id: string;
|
|
30
30
|
type: GraphNodeType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/pipeline/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIvF;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAIxE,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAI1E,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,WAAW,GACX,aAAa,GACb,KAAK,GACL,KAAK,GACL,aAAa,GACb,UAAU,CAAC;AAIf,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,mBAAmB,GACnB,qBAAqB,GACrB,aAAa,GACb,aAAa,GACb,cAAc,GACd,WAAW,CAAC;AAIhB,MAAM,MAAM,eAAe,GACvB,QAAQ,GACR,WAAW,GACX,SAAS,GACT,QAAQ,GACR,YAAY,CAAC;AAIjB,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,CAAC;AAIlE,MAAM,MAAM,YAAY,GACpB,kBAAkB,GAClB,qBAAqB,GACrB,oBAAoB,GACpB,kCAAkC,GAClC,wBAAwB,GACxB,qBAAqB,CAAC;AAE1B,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAI5D,MAAM,MAAM,aAAa,GAErB,UAAU,GACV,WAAW,GACX,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,OAAO,GACP,kBAAkB,GAClB,OAAO,GACP,MAAM,GACN,OAAO,GACP,UAAU,GAEV,WAAW,GACX,YAAY,GACZ,WAAW,GACX,WAAW,GACX,SAAS,GACT,QAAQ,GACR,iBAAiB,GAEjB,eAAe,GACf,eAAe,GACf,UAAU,GACV,eAAe,GACf,YAAY,CAAC;AAIjB,MAAM,MAAM,aAAa,GACrB,SAAS,GACT,OAAO,GACP,WAAW,GACX,QAAQ,GACR,SAAS,GACT,OAAO,GACP,SAAS,GACT,SAAS,GACT,gBAAgB,GAChB,OAAO,GACP,aAAa,GACb,kBAAkB,GAClB,YAAY,GACZ,aAAa,GACb,UAAU,GACV,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/pipeline/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "api-tests-coverage",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.17",
|
|
4
4
|
"description": "CLI and library to measure how thoroughly your test suite exercises your API surface area",
|
|
5
5
|
"main": "dist/src/lib/index.js",
|
|
6
6
|
"types": "dist/src/lib/index.d.ts",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
],
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
|
33
|
-
"url": "https://github.com/
|
|
33
|
+
"url": "https://github.com/q-intel/apiTestsCoverageAnalyzer.git"
|
|
34
34
|
},
|
|
35
|
-
"homepage": "https://github.com/
|
|
35
|
+
"homepage": "https://github.com/q-intel/apiTestsCoverageAnalyzer#readme",
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "tsc",
|