api-tests-coverage 1.0.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.
- package/README.md +703 -0
- package/config.yaml.example +227 -0
- package/dist/action/src/index.d.ts +2 -0
- package/dist/action/src/index.d.ts.map +1 -0
- package/dist/action/src/index.js +349 -0
- package/dist/action/src/prComment.d.ts +34 -0
- package/dist/action/src/prComment.d.ts.map +1 -0
- package/dist/action/src/prComment.js +146 -0
- package/dist/src/ast/astAnalysisOrchestrator.d.ts +36 -0
- package/dist/src/ast/astAnalysisOrchestrator.d.ts.map +1 -0
- package/dist/src/ast/astAnalysisOrchestrator.js +123 -0
- package/dist/src/ast/astTypes.d.ts +105 -0
- package/dist/src/ast/astTypes.d.ts.map +1 -0
- package/dist/src/ast/astTypes.js +9 -0
- package/dist/src/ast/languageAnalyzer.d.ts +46 -0
- package/dist/src/ast/languageAnalyzer.d.ts.map +1 -0
- package/dist/src/ast/languageAnalyzer.js +9 -0
- package/dist/src/ast/languageCapabilities.d.ts +24 -0
- package/dist/src/ast/languageCapabilities.d.ts.map +1 -0
- package/dist/src/ast/languageCapabilities.js +92 -0
- package/dist/src/ast/parseFile.d.ts +16 -0
- package/dist/src/ast/parseFile.d.ts.map +1 -0
- package/dist/src/ast/parseFile.js +65 -0
- package/dist/src/ast/parserRegistry.d.ts +39 -0
- package/dist/src/ast/parserRegistry.d.ts.map +1 -0
- package/dist/src/ast/parserRegistry.js +66 -0
- package/dist/src/buildSummary.d.ts +26 -0
- package/dist/src/buildSummary.d.ts.map +1 -0
- package/dist/src/buildSummary.js +193 -0
- package/dist/src/businessCoverage.d.ts +68 -0
- package/dist/src/businessCoverage.d.ts.map +1 -0
- package/dist/src/businessCoverage.js +290 -0
- package/dist/src/compatibilityCoverage.d.ts +83 -0
- package/dist/src/compatibilityCoverage.d.ts.map +1 -0
- package/dist/src/compatibilityCoverage.js +501 -0
- package/dist/src/config/defaultConfig.d.ts +9 -0
- package/dist/src/config/defaultConfig.d.ts.map +1 -0
- package/dist/src/config/defaultConfig.js +97 -0
- package/dist/src/config/index.d.ts +12 -0
- package/dist/src/config/index.d.ts.map +1 -0
- package/dist/src/config/index.js +37 -0
- package/dist/src/config/loadConfig.d.ts +29 -0
- package/dist/src/config/loadConfig.d.ts.map +1 -0
- package/dist/src/config/loadConfig.js +135 -0
- package/dist/src/config/mergeConfig.d.ts +15 -0
- package/dist/src/config/mergeConfig.d.ts.map +1 -0
- package/dist/src/config/mergeConfig.js +57 -0
- package/dist/src/config/schema.d.ts +15 -0
- package/dist/src/config/schema.d.ts.map +1 -0
- package/dist/src/config/schema.js +30 -0
- package/dist/src/config/types.d.ts +175 -0
- package/dist/src/config/types.d.ts.map +1 -0
- package/dist/src/config/types.js +9 -0
- package/dist/src/config/validateConfig.d.ts +22 -0
- package/dist/src/config/validateConfig.d.ts.map +1 -0
- package/dist/src/config/validateConfig.js +171 -0
- package/dist/src/config.d.ts +168 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +204 -0
- package/dist/src/coverage/deep-analysis/callGraph.d.ts +67 -0
- package/dist/src/coverage/deep-analysis/callGraph.d.ts.map +1 -0
- package/dist/src/coverage/deep-analysis/callGraph.js +275 -0
- package/dist/src/coverage/deep-analysis/deepEndpointResolver.d.ts +23 -0
- package/dist/src/coverage/deep-analysis/deepEndpointResolver.d.ts.map +1 -0
- package/dist/src/coverage/deep-analysis/deepEndpointResolver.js +394 -0
- package/dist/src/coverage/deep-analysis/index.d.ts +17 -0
- package/dist/src/coverage/deep-analysis/index.d.ts.map +1 -0
- package/dist/src/coverage/deep-analysis/index.js +63 -0
- package/dist/src/coverage/deep-analysis/resolveAssertions.d.ts +60 -0
- package/dist/src/coverage/deep-analysis/resolveAssertions.d.ts.map +1 -0
- package/dist/src/coverage/deep-analysis/resolveAssertions.js +121 -0
- package/dist/src/coverage/deep-analysis/resolveConstants.d.ts +36 -0
- package/dist/src/coverage/deep-analysis/resolveConstants.d.ts.map +1 -0
- package/dist/src/coverage/deep-analysis/resolveConstants.js +92 -0
- package/dist/src/coverage/deep-analysis/resolveEnums.d.ts +55 -0
- package/dist/src/coverage/deep-analysis/resolveEnums.d.ts.map +1 -0
- package/dist/src/coverage/deep-analysis/resolveEnums.js +152 -0
- package/dist/src/coverage/deep-analysis/resolveMethodChains.d.ts +70 -0
- package/dist/src/coverage/deep-analysis/resolveMethodChains.d.ts.map +1 -0
- package/dist/src/coverage/deep-analysis/resolveMethodChains.js +152 -0
- package/dist/src/coverage/deep-analysis/resolvePaths.d.ts +80 -0
- package/dist/src/coverage/deep-analysis/resolvePaths.d.ts.map +1 -0
- package/dist/src/coverage/deep-analysis/resolvePaths.js +216 -0
- package/dist/src/coverage/deep-analysis/resolveRequestWrappers.d.ts +71 -0
- package/dist/src/coverage/deep-analysis/resolveRequestWrappers.d.ts.map +1 -0
- package/dist/src/coverage/deep-analysis/resolveRequestWrappers.js +226 -0
- package/dist/src/coverage/deep-analysis/symbolTable.d.ts +58 -0
- package/dist/src/coverage/deep-analysis/symbolTable.d.ts.map +1 -0
- package/dist/src/coverage/deep-analysis/symbolTable.js +230 -0
- package/dist/src/coverage/deep-analysis/types.d.ts +122 -0
- package/dist/src/coverage/deep-analysis/types.d.ts.map +1 -0
- package/dist/src/coverage/deep-analysis/types.js +21 -0
- package/dist/src/discovery/fileClassifier.d.ts +50 -0
- package/dist/src/discovery/fileClassifier.d.ts.map +1 -0
- package/dist/src/discovery/fileClassifier.js +238 -0
- package/dist/src/discovery/projectDiscovery.d.ts +66 -0
- package/dist/src/discovery/projectDiscovery.d.ts.map +1 -0
- package/dist/src/discovery/projectDiscovery.js +287 -0
- package/dist/src/endpointCoverage.d.ts +70 -0
- package/dist/src/endpointCoverage.d.ts.map +1 -0
- package/dist/src/endpointCoverage.js +381 -0
- package/dist/src/errorCoverage.d.ts +93 -0
- package/dist/src/errorCoverage.d.ts.map +1 -0
- package/dist/src/errorCoverage.js +698 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +1441 -0
- package/dist/src/inference/businessRuleInference.d.ts +63 -0
- package/dist/src/inference/businessRuleInference.d.ts.map +1 -0
- package/dist/src/inference/businessRuleInference.js +268 -0
- package/dist/src/inference/integrationFlowInference.d.ts +56 -0
- package/dist/src/inference/integrationFlowInference.d.ts.map +1 -0
- package/dist/src/inference/integrationFlowInference.js +266 -0
- package/dist/src/integrationCoverage.d.ts +72 -0
- package/dist/src/integrationCoverage.d.ts.map +1 -0
- package/dist/src/integrationCoverage.js +317 -0
- package/dist/src/intelligence/index.d.ts +20 -0
- package/dist/src/intelligence/index.d.ts.map +1 -0
- package/dist/src/intelligence/index.js +105 -0
- package/dist/src/intelligence/linkageEngine.d.ts +20 -0
- package/dist/src/intelligence/linkageEngine.d.ts.map +1 -0
- package/dist/src/intelligence/linkageEngine.js +522 -0
- package/dist/src/intelligence/markdownReporter.d.ts +12 -0
- package/dist/src/intelligence/markdownReporter.d.ts.map +1 -0
- package/dist/src/intelligence/markdownReporter.js +265 -0
- package/dist/src/intelligence/riskScoring.d.ts +53 -0
- package/dist/src/intelligence/riskScoring.d.ts.map +1 -0
- package/dist/src/intelligence/riskScoring.js +181 -0
- package/dist/src/intelligence/types.d.ts +121 -0
- package/dist/src/intelligence/types.d.ts.map +1 -0
- package/dist/src/intelligence/types.js +8 -0
- package/dist/src/languageDetection.d.ts +100 -0
- package/dist/src/languageDetection.d.ts.map +1 -0
- package/dist/src/languageDetection.js +349 -0
- package/dist/src/languages/java/index.d.ts +16 -0
- package/dist/src/languages/java/index.d.ts.map +1 -0
- package/dist/src/languages/java/index.js +103 -0
- package/dist/src/languages/java/parser.d.ts +7 -0
- package/dist/src/languages/java/parser.d.ts.map +1 -0
- package/dist/src/languages/java/parser.js +50 -0
- package/dist/src/languages/java/semanticBuilder.d.ts +21 -0
- package/dist/src/languages/java/semanticBuilder.d.ts.map +1 -0
- package/dist/src/languages/java/semanticBuilder.js +358 -0
- package/dist/src/languages/javascript/annotationExtractor.d.ts +20 -0
- package/dist/src/languages/javascript/annotationExtractor.d.ts.map +1 -0
- package/dist/src/languages/javascript/annotationExtractor.js +94 -0
- package/dist/src/languages/javascript/assertionResolver.d.ts +18 -0
- package/dist/src/languages/javascript/assertionResolver.d.ts.map +1 -0
- package/dist/src/languages/javascript/assertionResolver.js +150 -0
- package/dist/src/languages/javascript/callResolver.d.ts +23 -0
- package/dist/src/languages/javascript/callResolver.d.ts.map +1 -0
- package/dist/src/languages/javascript/callResolver.js +236 -0
- package/dist/src/languages/javascript/httpInteractionExtractor.d.ts +23 -0
- package/dist/src/languages/javascript/httpInteractionExtractor.d.ts.map +1 -0
- package/dist/src/languages/javascript/httpInteractionExtractor.js +205 -0
- package/dist/src/languages/javascript/index.d.ts +20 -0
- package/dist/src/languages/javascript/index.d.ts.map +1 -0
- package/dist/src/languages/javascript/index.js +136 -0
- package/dist/src/languages/javascript/parser.d.ts +14 -0
- package/dist/src/languages/javascript/parser.d.ts.map +1 -0
- package/dist/src/languages/javascript/parser.js +38 -0
- package/dist/src/languages/javascript/symbolResolver.d.ts +31 -0
- package/dist/src/languages/javascript/symbolResolver.d.ts.map +1 -0
- package/dist/src/languages/javascript/symbolResolver.js +183 -0
- package/dist/src/languages/kotlin/index.d.ts +16 -0
- package/dist/src/languages/kotlin/index.d.ts.map +1 -0
- package/dist/src/languages/kotlin/index.js +151 -0
- package/dist/src/languages/kotlin/parser.d.ts +11 -0
- package/dist/src/languages/kotlin/parser.d.ts.map +1 -0
- package/dist/src/languages/kotlin/parser.js +74 -0
- package/dist/src/languages/python/index.d.ts +15 -0
- package/dist/src/languages/python/index.d.ts.map +1 -0
- package/dist/src/languages/python/index.js +293 -0
- package/dist/src/languages/ruby/index.d.ts +15 -0
- package/dist/src/languages/ruby/index.d.ts.map +1 -0
- package/dist/src/languages/ruby/index.js +274 -0
- package/dist/src/languages/shared/treeSitterUtils.d.ts +43 -0
- package/dist/src/languages/shared/treeSitterUtils.d.ts.map +1 -0
- package/dist/src/languages/shared/treeSitterUtils.js +100 -0
- package/dist/src/languages/typescript/index.d.ts +14 -0
- package/dist/src/languages/typescript/index.d.ts.map +1 -0
- package/dist/src/languages/typescript/index.js +25 -0
- package/dist/src/lib/index.d.ts +228 -0
- package/dist/src/lib/index.d.ts.map +1 -0
- package/dist/src/lib/index.js +486 -0
- package/dist/src/mcp/client/index.d.ts +37 -0
- package/dist/src/mcp/client/index.d.ts.map +1 -0
- package/dist/src/mcp/client/index.js +235 -0
- package/dist/src/mcp/config.d.ts +50 -0
- package/dist/src/mcp/config.d.ts.map +1 -0
- package/dist/src/mcp/config.js +125 -0
- package/dist/src/mcp/events.d.ts +24 -0
- package/dist/src/mcp/events.d.ts.map +1 -0
- package/dist/src/mcp/events.js +48 -0
- package/dist/src/mcp/fallback/index.d.ts +50 -0
- package/dist/src/mcp/fallback/index.d.ts.map +1 -0
- package/dist/src/mcp/fallback/index.js +216 -0
- package/dist/src/mcp/index.d.ts +67 -0
- package/dist/src/mcp/index.d.ts.map +1 -0
- package/dist/src/mcp/index.js +212 -0
- package/dist/src/mcp/normalizer.d.ts +21 -0
- package/dist/src/mcp/normalizer.d.ts.map +1 -0
- package/dist/src/mcp/normalizer.js +99 -0
- package/dist/src/mcp/prompts/index.d.ts +86 -0
- package/dist/src/mcp/prompts/index.d.ts.map +1 -0
- package/dist/src/mcp/prompts/index.js +304 -0
- package/dist/src/mcp/templates/index.d.ts +35 -0
- package/dist/src/mcp/templates/index.d.ts.map +1 -0
- package/dist/src/mcp/templates/index.js +143 -0
- package/dist/src/mcp/testing/mock-server/index.d.ts +47 -0
- package/dist/src/mcp/testing/mock-server/index.d.ts.map +1 -0
- package/dist/src/mcp/testing/mock-server/index.js +157 -0
- package/dist/src/mcp/types.d.ts +127 -0
- package/dist/src/mcp/types.d.ts.map +1 -0
- package/dist/src/mcp/types.js +8 -0
- package/dist/src/observability.d.ts +138 -0
- package/dist/src/observability.d.ts.map +1 -0
- package/dist/src/observability.js +519 -0
- package/dist/src/parameterCoverage.d.ts +75 -0
- package/dist/src/parameterCoverage.d.ts.map +1 -0
- package/dist/src/parameterCoverage.js +629 -0
- package/dist/src/perfResilienceCoverage.d.ts +155 -0
- package/dist/src/perfResilienceCoverage.d.ts.map +1 -0
- package/dist/src/perfResilienceCoverage.js +670 -0
- package/dist/src/pluginLoader.d.ts +51 -0
- package/dist/src/pluginLoader.d.ts.map +1 -0
- package/dist/src/pluginLoader.js +72 -0
- package/dist/src/publishing.d.ts +63 -0
- package/dist/src/publishing.d.ts.map +1 -0
- package/dist/src/publishing.js +379 -0
- package/dist/src/qualityGate.d.ts +58 -0
- package/dist/src/qualityGate.d.ts.map +1 -0
- package/dist/src/qualityGate.js +118 -0
- package/dist/src/reporting.d.ts +41 -0
- package/dist/src/reporting.d.ts.map +1 -0
- package/dist/src/reporting.js +278 -0
- package/dist/src/screenshots.d.ts +71 -0
- package/dist/src/screenshots.d.ts.map +1 -0
- package/dist/src/screenshots.js +141 -0
- package/dist/src/security/gate/index.d.ts +11 -0
- package/dist/src/security/gate/index.d.ts.map +1 -0
- package/dist/src/security/gate/index.js +65 -0
- package/dist/src/security/index.d.ts +30 -0
- package/dist/src/security/index.d.ts.map +1 -0
- package/dist/src/security/index.js +342 -0
- package/dist/src/security/normalizers/semgrep.d.ts +10 -0
- package/dist/src/security/normalizers/semgrep.d.ts.map +1 -0
- package/dist/src/security/normalizers/semgrep.js +104 -0
- package/dist/src/security/normalizers/trivy.d.ts +10 -0
- package/dist/src/security/normalizers/trivy.d.ts.map +1 -0
- package/dist/src/security/normalizers/trivy.js +78 -0
- package/dist/src/security/normalizers/zap.d.ts +10 -0
- package/dist/src/security/normalizers/zap.d.ts.map +1 -0
- package/dist/src/security/normalizers/zap.js +104 -0
- package/dist/src/security/scanners/semgrep.d.ts +6 -0
- package/dist/src/security/scanners/semgrep.d.ts.map +1 -0
- package/dist/src/security/scanners/semgrep.js +125 -0
- package/dist/src/security/scanners/trivy.d.ts +6 -0
- package/dist/src/security/scanners/trivy.d.ts.map +1 -0
- package/dist/src/security/scanners/trivy.js +115 -0
- package/dist/src/security/scanners/zap.d.ts +6 -0
- package/dist/src/security/scanners/zap.d.ts.map +1 -0
- package/dist/src/security/scanners/zap.js +135 -0
- package/dist/src/security/types.d.ts +146 -0
- package/dist/src/security/types.d.ts.map +1 -0
- package/dist/src/security/types.js +6 -0
- package/dist/src/securityCoverage.d.ts +116 -0
- package/dist/src/securityCoverage.d.ts.map +1 -0
- package/dist/src/securityCoverage.js +725 -0
- package/dist/src/summary/buildSummary.d.ts +28 -0
- package/dist/src/summary/buildSummary.d.ts.map +1 -0
- package/dist/src/summary/buildSummary.js +257 -0
- package/dist/src/summary/evaluateMetrics.d.ts +31 -0
- package/dist/src/summary/evaluateMetrics.d.ts.map +1 -0
- package/dist/src/summary/evaluateMetrics.js +118 -0
- package/dist/src/summary/index.d.ts +10 -0
- package/dist/src/summary/index.d.ts.map +1 -0
- package/dist/src/summary/index.js +22 -0
- package/dist/src/summary/markdownRenderer.d.ts +139 -0
- package/dist/src/summary/markdownRenderer.d.ts.map +1 -0
- package/dist/src/summary/markdownRenderer.js +459 -0
- package/dist/src/summary/prSummary.d.ts +24 -0
- package/dist/src/summary/prSummary.d.ts.map +1 -0
- package/dist/src/summary/prSummary.js +233 -0
- package/dist/src/summary/summaryTypes.d.ts +35 -0
- package/dist/src/summary/summaryTypes.d.ts.map +1 -0
- package/dist/src/summary/summaryTypes.js +27 -0
- package/package.json +84 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Deep Code Analysis — Assertion Awareness
|
|
4
|
+
*
|
|
5
|
+
* Associates HTTP response variables with their downstream assertions to
|
|
6
|
+
* determine whether a request is "meaningfully" tested (i.e. the response
|
|
7
|
+
* is actually checked) rather than just called incidentally.
|
|
8
|
+
*
|
|
9
|
+
* Supported patterns:
|
|
10
|
+
*
|
|
11
|
+
* TypeScript (Jest / Supertest):
|
|
12
|
+
* const response = api.get('/users');
|
|
13
|
+
* expect(response.status).toBe(200);
|
|
14
|
+
* expect(response.body).toEqual({ ... });
|
|
15
|
+
*
|
|
16
|
+
* Java (JUnit / RestAssured):
|
|
17
|
+
* Response response = api.get("/users");
|
|
18
|
+
* assertEquals(200, response.getStatusCode());
|
|
19
|
+
* assertThat(response.getBody(), ...).isNotEmpty();
|
|
20
|
+
*
|
|
21
|
+
* Python (pytest / unittest):
|
|
22
|
+
* response = client.get('/users')
|
|
23
|
+
* assert response.status_code == 200
|
|
24
|
+
* self.assertEqual(response.status_code, 200)
|
|
25
|
+
*
|
|
26
|
+
* Kotlin:
|
|
27
|
+
* val response = client.get("/users")
|
|
28
|
+
* assertEquals(200, response.status)
|
|
29
|
+
* assertThat(response.body).isNotNull()
|
|
30
|
+
*/
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.isAssertionLinked = isAssertionLinked;
|
|
33
|
+
exports.extractResponseVariables = extractResponseVariables;
|
|
34
|
+
exports.buildAssertionMap = buildAssertionMap;
|
|
35
|
+
// ─── Assertion detection ──────────────────────────────────────────────────────
|
|
36
|
+
/**
|
|
37
|
+
* Detect whether a response variable is followed by at least one assertion.
|
|
38
|
+
*
|
|
39
|
+
* This is a lightweight heuristic: we check whether the response variable
|
|
40
|
+
* name appears inside an expect(), assert, assertEquals, assertThat, or
|
|
41
|
+
* similar assertion call within the same file.
|
|
42
|
+
*
|
|
43
|
+
* Returns true when at least one assertion is found.
|
|
44
|
+
*/
|
|
45
|
+
function isAssertionLinked(responseVar, content) {
|
|
46
|
+
if (!responseVar)
|
|
47
|
+
return false;
|
|
48
|
+
// TypeScript/JS: expect(responseName.xxx)
|
|
49
|
+
const jsExpect = new RegExp(`\\bexpect\\s*\\(\\s*${escapeRegex(responseVar)}\\b`, 'g');
|
|
50
|
+
if (jsExpect.test(content))
|
|
51
|
+
return true;
|
|
52
|
+
// Java/Kotlin: assertEquals(xxx, responseName.getXxx())
|
|
53
|
+
// assertThat(responseName.xxx)
|
|
54
|
+
const javaAssert = new RegExp(`\\b(?:assertEquals|assertNotNull|assertThat|assertFalse|assertTrue|assertNull)\\s*\\([^)]*\\b${escapeRegex(responseVar)}\\b`, 'g');
|
|
55
|
+
if (javaAssert.test(content))
|
|
56
|
+
return true;
|
|
57
|
+
// Python: assert responseName.status_code
|
|
58
|
+
const pyAssert = new RegExp(`\\bassert\\s+${escapeRegex(responseVar)}\\b`, 'g');
|
|
59
|
+
if (pyAssert.test(content))
|
|
60
|
+
return true;
|
|
61
|
+
// Python unittest: self.assertEqual(xxx, responseName.xxx)
|
|
62
|
+
const pyUnitAssert = new RegExp(`\\bself\\.assert(?:Equal|NotEqual|In|NotIn|True|False)\\s*\\([^)]*\\b${escapeRegex(responseVar)}\\b`, 'g');
|
|
63
|
+
if (pyUnitAssert.test(content))
|
|
64
|
+
return true;
|
|
65
|
+
// Kotlin / Java: response.status shouldBe 200 (Kotest)
|
|
66
|
+
const kotestAssert = new RegExp(`\\b${escapeRegex(responseVar)}\\b[^\\n]*\\bshould`, 'g');
|
|
67
|
+
if (kotestAssert.test(content))
|
|
68
|
+
return true;
|
|
69
|
+
// RestAssured: .then().statusCode(200) chained on the same variable
|
|
70
|
+
const raAssert = new RegExp(`\\b${escapeRegex(responseVar)}\\b[^\\n]*\\.then\\(\\)`, 'g');
|
|
71
|
+
if (raAssert.test(content))
|
|
72
|
+
return true;
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Extract all response variable names from HTTP call sites in a file.
|
|
77
|
+
*
|
|
78
|
+
* Returns a map of varName → { method, path } for all assignments like:
|
|
79
|
+
* const resp = client.get('/users')
|
|
80
|
+
* Response res = api.post("/users")
|
|
81
|
+
* response = client.get('/path')
|
|
82
|
+
*/
|
|
83
|
+
function extractResponseVariables(content) {
|
|
84
|
+
const results = [];
|
|
85
|
+
// TypeScript/JavaScript: const|let|var response = ....(get|post|...)(path)
|
|
86
|
+
const jsPattern = /\b(?:const|let|var)\s+([A-Za-z_$][A-Za-z0-9_$]*)\s*=\s*(?:\w+\.)+?(get|post|put|patch|delete|head|options)\s*\(\s*['"`]([^'"`]+)['"`]/gi;
|
|
87
|
+
let m;
|
|
88
|
+
while ((m = jsPattern.exec(content)) !== null) {
|
|
89
|
+
results.push({ varName: m[1], method: m[2].toUpperCase(), path: m[3] });
|
|
90
|
+
}
|
|
91
|
+
// Java/Kotlin: Type varName = ....(get|post|...)(path)
|
|
92
|
+
// Allow method calls with () in the chain: given(), spec(), etc.
|
|
93
|
+
const javaPattern = /\b(?:Response|HttpResponse|MockHttpServletResponse|ResponseEntity|ValidatableResponse|ExtractableResponse)\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(?:\w+(?:\([^)]*\))?[.\s]+)*(get|post|put|patch|delete|head|options)\s*\(\s*["'`]([^"'`]+)["'`]/gi;
|
|
94
|
+
while ((m = javaPattern.exec(content)) !== null) {
|
|
95
|
+
results.push({ varName: m[1], method: m[2].toUpperCase(), path: m[3] });
|
|
96
|
+
}
|
|
97
|
+
// Python: response = client.get('/path') or res = requests.post('/path')
|
|
98
|
+
const pyPattern = /^(\s*)([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(?:self\.)?(?:client|requests?|httpx)\.(get|post|put|patch|delete|head|options)\s*\(\s*['"]([^'"]+)['"]/gm;
|
|
99
|
+
while ((m = pyPattern.exec(content)) !== null) {
|
|
100
|
+
results.push({ varName: m[2], method: m[3].toUpperCase(), path: m[4] });
|
|
101
|
+
}
|
|
102
|
+
return results;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* For each response variable in the content, determine if it has an
|
|
106
|
+
* associated assertion.
|
|
107
|
+
*
|
|
108
|
+
* Returns a map: varName → assertionLinked (boolean)
|
|
109
|
+
*/
|
|
110
|
+
function buildAssertionMap(content) {
|
|
111
|
+
const responseVars = extractResponseVariables(content);
|
|
112
|
+
const map = new Map();
|
|
113
|
+
for (const { varName } of responseVars) {
|
|
114
|
+
map.set(varName, isAssertionLinked(varName, content));
|
|
115
|
+
}
|
|
116
|
+
return map;
|
|
117
|
+
}
|
|
118
|
+
// ─── Utility ──────────────────────────────────────────────────────────────────
|
|
119
|
+
function escapeRegex(s) {
|
|
120
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
121
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep Code Analysis — Constant Resolution
|
|
3
|
+
*
|
|
4
|
+
* Given a token that may be a variable or constant reference, looks it up in
|
|
5
|
+
* the symbol table and returns the resolved literal string value.
|
|
6
|
+
*/
|
|
7
|
+
import type { SymbolTable } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* Attempt to resolve a raw argument token found in an HTTP call to a concrete
|
|
10
|
+
* string value.
|
|
11
|
+
*
|
|
12
|
+
* Examples:
|
|
13
|
+
* resolveToken("USERS_PATH", table) → "/users" (when table has USERS_PATH → /users)
|
|
14
|
+
* resolveToken("'/users'", table) → "/users" (quoted literal, no lookup needed)
|
|
15
|
+
* resolveToken("/users", table) → "/users" (already a path)
|
|
16
|
+
*
|
|
17
|
+
* Returns undefined when the value cannot be resolved.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveToken(token: string, table: SymbolTable): string | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Given an array of path fragment tokens (e.g. from a concatenation), resolve
|
|
22
|
+
* each one and join them into a single path string.
|
|
23
|
+
*
|
|
24
|
+
* Returns undefined when any segment cannot be resolved to a string.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveFragments(fragments: string[], table: SymbolTable): string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Scan source content for all constant/variable assignments with string literal
|
|
29
|
+
* values and return the discovered symbol names along with their raw values as
|
|
30
|
+
* a simple Record<string, string>.
|
|
31
|
+
*
|
|
32
|
+
* This utility is used by tests to inspect resolution results without going through
|
|
33
|
+
* the full symbol table builder.
|
|
34
|
+
*/
|
|
35
|
+
export declare function extractStringConstants(content: string): Record<string, string>;
|
|
36
|
+
//# sourceMappingURL=resolveConstants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveConstants.d.ts","sourceRoot":"","sources":["../../../../src/coverage/deep-analysis/resolveConstants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG3C;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAuBlF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAQ5F;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA2B9E"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Deep Code Analysis — Constant Resolution
|
|
4
|
+
*
|
|
5
|
+
* Given a token that may be a variable or constant reference, looks it up in
|
|
6
|
+
* the symbol table and returns the resolved literal string value.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.resolveToken = resolveToken;
|
|
10
|
+
exports.resolveFragments = resolveFragments;
|
|
11
|
+
exports.extractStringConstants = extractStringConstants;
|
|
12
|
+
const symbolTable_1 = require("./symbolTable");
|
|
13
|
+
/**
|
|
14
|
+
* Attempt to resolve a raw argument token found in an HTTP call to a concrete
|
|
15
|
+
* string value.
|
|
16
|
+
*
|
|
17
|
+
* Examples:
|
|
18
|
+
* resolveToken("USERS_PATH", table) → "/users" (when table has USERS_PATH → /users)
|
|
19
|
+
* resolveToken("'/users'", table) → "/users" (quoted literal, no lookup needed)
|
|
20
|
+
* resolveToken("/users", table) → "/users" (already a path)
|
|
21
|
+
*
|
|
22
|
+
* Returns undefined when the value cannot be resolved.
|
|
23
|
+
*/
|
|
24
|
+
function resolveToken(token, table) {
|
|
25
|
+
const trimmed = token.trim();
|
|
26
|
+
// Already a quoted string literal — strip quotes
|
|
27
|
+
if (/^['"`]/.test(trimmed) && /['"`]$/.test(trimmed)) {
|
|
28
|
+
return trimmed.slice(1, -1);
|
|
29
|
+
}
|
|
30
|
+
// Already a bare path
|
|
31
|
+
if (trimmed.startsWith('/'))
|
|
32
|
+
return trimmed;
|
|
33
|
+
// Dotted access: e.g. Routes.USERS, Paths.USERS_BY_ID
|
|
34
|
+
if (trimmed.includes('.')) {
|
|
35
|
+
const resolved = (0, symbolTable_1.resolveSymbol)(trimmed, table);
|
|
36
|
+
if (resolved !== undefined)
|
|
37
|
+
return resolved;
|
|
38
|
+
// Try just the member part (Foo.BAR → look up BAR)
|
|
39
|
+
const member = trimmed.split('.').pop();
|
|
40
|
+
return (0, symbolTable_1.resolveSymbol)(member, table);
|
|
41
|
+
}
|
|
42
|
+
// Simple identifier
|
|
43
|
+
return (0, symbolTable_1.resolveSymbol)(trimmed, table);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Given an array of path fragment tokens (e.g. from a concatenation), resolve
|
|
47
|
+
* each one and join them into a single path string.
|
|
48
|
+
*
|
|
49
|
+
* Returns undefined when any segment cannot be resolved to a string.
|
|
50
|
+
*/
|
|
51
|
+
function resolveFragments(fragments, table) {
|
|
52
|
+
const parts = [];
|
|
53
|
+
for (const frag of fragments) {
|
|
54
|
+
const resolved = resolveToken(frag.trim(), table);
|
|
55
|
+
if (resolved === undefined)
|
|
56
|
+
return undefined;
|
|
57
|
+
parts.push(resolved);
|
|
58
|
+
}
|
|
59
|
+
return parts.join('');
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Scan source content for all constant/variable assignments with string literal
|
|
63
|
+
* values and return the discovered symbol names along with their raw values as
|
|
64
|
+
* a simple Record<string, string>.
|
|
65
|
+
*
|
|
66
|
+
* This utility is used by tests to inspect resolution results without going through
|
|
67
|
+
* the full symbol table builder.
|
|
68
|
+
*/
|
|
69
|
+
function extractStringConstants(content) {
|
|
70
|
+
const result = {};
|
|
71
|
+
// TypeScript/JavaScript: const/let/var NAME = 'value'
|
|
72
|
+
const jsPattern = /\b(?:const|let|var)\s+([A-Za-z_$][A-Za-z0-9_$]*)\s*=\s*['"`]([^'"`\n]+)['"`]/g;
|
|
73
|
+
let m;
|
|
74
|
+
while ((m = jsPattern.exec(content)) !== null) {
|
|
75
|
+
result[m[1]] = m[2];
|
|
76
|
+
}
|
|
77
|
+
// Java/Kotlin: String/val NAME = "value"
|
|
78
|
+
const javaPattern = /\bString\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*"([^"\n]+)"/g;
|
|
79
|
+
while ((m = javaPattern.exec(content)) !== null) {
|
|
80
|
+
result[m[1]] = m[2];
|
|
81
|
+
}
|
|
82
|
+
const kotlinPattern = /\b(?:const\s+)?val\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*["']([^"'\n]+)["']/g;
|
|
83
|
+
while ((m = kotlinPattern.exec(content)) !== null) {
|
|
84
|
+
result[m[1]] = m[2];
|
|
85
|
+
}
|
|
86
|
+
// Python: NAME = 'value' (allow optional leading whitespace for indented blocks)
|
|
87
|
+
const pyPattern = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*['"]([^'"\n]+)['"]/gm;
|
|
88
|
+
while ((m = pyPattern.exec(content)) !== null) {
|
|
89
|
+
result[m[1]] = m[2];
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep Code Analysis — Enum Resolution
|
|
3
|
+
*
|
|
4
|
+
* Resolves enum member references used as endpoint path arguments across all
|
|
5
|
+
* supported languages.
|
|
6
|
+
*
|
|
7
|
+
* Supported patterns:
|
|
8
|
+
*
|
|
9
|
+
* TypeScript:
|
|
10
|
+
* enum Routes { USERS = '/users' }
|
|
11
|
+
* client.get(Routes.USERS) → GET /users
|
|
12
|
+
*
|
|
13
|
+
* Java:
|
|
14
|
+
* enum Routes { USERS("/users"); ... }
|
|
15
|
+
* api.get(Routes.USERS.getPath()) → GET /users
|
|
16
|
+
*
|
|
17
|
+
* Kotlin:
|
|
18
|
+
* enum class Routes(val path: String) { USERS("/users") }
|
|
19
|
+
* client.get(Routes.USERS.path) → GET /users
|
|
20
|
+
*
|
|
21
|
+
* Python:
|
|
22
|
+
* class Routes(Enum): USERS = "/users"
|
|
23
|
+
* client.get(Routes.USERS.value) → GET /users
|
|
24
|
+
*/
|
|
25
|
+
import type { SymbolTable } from './types';
|
|
26
|
+
/**
|
|
27
|
+
* Attempt to resolve an enum reference token to its literal path value.
|
|
28
|
+
*
|
|
29
|
+
* The token may be in any of these forms:
|
|
30
|
+
* Routes.USERS
|
|
31
|
+
* Routes.USERS.path (Kotlin)
|
|
32
|
+
* Routes.USERS.value (Python)
|
|
33
|
+
* Routes.USERS.getPath() (Java)
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveEnumToken(token: string, table: SymbolTable): string | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Extract all enum declarations from TypeScript/JavaScript source and return
|
|
38
|
+
* a map of EnumName.MEMBER → value.
|
|
39
|
+
*/
|
|
40
|
+
export declare function extractTsEnumValues(content: string): Record<string, string>;
|
|
41
|
+
/**
|
|
42
|
+
* Extract all enum values from Java source.
|
|
43
|
+
* Supports constructor-style enums: MEMBER("value")
|
|
44
|
+
*/
|
|
45
|
+
export declare function extractJavaEnumValues(content: string): Record<string, string>;
|
|
46
|
+
/**
|
|
47
|
+
* Extract all enum values from Kotlin source.
|
|
48
|
+
*/
|
|
49
|
+
export declare function extractKotlinEnumValues(content: string): Record<string, string>;
|
|
50
|
+
/**
|
|
51
|
+
* Extract all enum values from Python source.
|
|
52
|
+
* Supports class Routes(Enum): MEMBER = "value"
|
|
53
|
+
*/
|
|
54
|
+
export declare function extractPythonEnumValues(content: string): Record<string, string>;
|
|
55
|
+
//# sourceMappingURL=resolveEnums.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveEnums.d.ts","sourceRoot":"","sources":["../../../../src/coverage/deep-analysis/resolveEnums.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG3C;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CA4BtF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgB3E;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgB7E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAe/E;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkB/E"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Deep Code Analysis — Enum Resolution
|
|
4
|
+
*
|
|
5
|
+
* Resolves enum member references used as endpoint path arguments across all
|
|
6
|
+
* supported languages.
|
|
7
|
+
*
|
|
8
|
+
* Supported patterns:
|
|
9
|
+
*
|
|
10
|
+
* TypeScript:
|
|
11
|
+
* enum Routes { USERS = '/users' }
|
|
12
|
+
* client.get(Routes.USERS) → GET /users
|
|
13
|
+
*
|
|
14
|
+
* Java:
|
|
15
|
+
* enum Routes { USERS("/users"); ... }
|
|
16
|
+
* api.get(Routes.USERS.getPath()) → GET /users
|
|
17
|
+
*
|
|
18
|
+
* Kotlin:
|
|
19
|
+
* enum class Routes(val path: String) { USERS("/users") }
|
|
20
|
+
* client.get(Routes.USERS.path) → GET /users
|
|
21
|
+
*
|
|
22
|
+
* Python:
|
|
23
|
+
* class Routes(Enum): USERS = "/users"
|
|
24
|
+
* client.get(Routes.USERS.value) → GET /users
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.resolveEnumToken = resolveEnumToken;
|
|
28
|
+
exports.extractTsEnumValues = extractTsEnumValues;
|
|
29
|
+
exports.extractJavaEnumValues = extractJavaEnumValues;
|
|
30
|
+
exports.extractKotlinEnumValues = extractKotlinEnumValues;
|
|
31
|
+
exports.extractPythonEnumValues = extractPythonEnumValues;
|
|
32
|
+
const symbolTable_1 = require("./symbolTable");
|
|
33
|
+
/**
|
|
34
|
+
* Attempt to resolve an enum reference token to its literal path value.
|
|
35
|
+
*
|
|
36
|
+
* The token may be in any of these forms:
|
|
37
|
+
* Routes.USERS
|
|
38
|
+
* Routes.USERS.path (Kotlin)
|
|
39
|
+
* Routes.USERS.value (Python)
|
|
40
|
+
* Routes.USERS.getPath() (Java)
|
|
41
|
+
*/
|
|
42
|
+
function resolveEnumToken(token, table) {
|
|
43
|
+
const t = token.trim();
|
|
44
|
+
// Direct table lookup (handles Routes.USERS and bare USERS)
|
|
45
|
+
const direct = (0, symbolTable_1.resolveSymbol)(t, table);
|
|
46
|
+
if (direct !== undefined)
|
|
47
|
+
return direct;
|
|
48
|
+
// Strip trailing .path, .value, .getPath(), .name, .ordinal()
|
|
49
|
+
const withoutSuffix = t.replace(/\.(path|value|getPath\(\)|name|ordinal\(\)|get[A-Za-z]+\(\))$/, '');
|
|
50
|
+
if (withoutSuffix !== t) {
|
|
51
|
+
const resolved = (0, symbolTable_1.resolveSymbol)(withoutSuffix, table);
|
|
52
|
+
if (resolved !== undefined)
|
|
53
|
+
return resolved;
|
|
54
|
+
// Try just the member (last segment before stripped suffix)
|
|
55
|
+
const parts = withoutSuffix.split('.');
|
|
56
|
+
if (parts.length >= 2) {
|
|
57
|
+
const member = parts[parts.length - 1];
|
|
58
|
+
const resolved2 = (0, symbolTable_1.resolveSymbol)(member, table);
|
|
59
|
+
if (resolved2 !== undefined)
|
|
60
|
+
return resolved2;
|
|
61
|
+
// Try Enum.MEMBER compound
|
|
62
|
+
const compound = parts.slice(-2).join('.');
|
|
63
|
+
const resolved3 = (0, symbolTable_1.resolveSymbol)(compound, table);
|
|
64
|
+
if (resolved3 !== undefined)
|
|
65
|
+
return resolved3;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Extract all enum declarations from TypeScript/JavaScript source and return
|
|
72
|
+
* a map of EnumName.MEMBER → value.
|
|
73
|
+
*/
|
|
74
|
+
function extractTsEnumValues(content) {
|
|
75
|
+
const result = {};
|
|
76
|
+
// Allow {param} segments inside enum body strings (e.g. "/users/{id}")
|
|
77
|
+
const enumPattern = /\benum\s+([A-Za-z_$][A-Za-z0-9_$]*)\s*\{((?:[^{}]|\{[^}]*\})*)\}/g;
|
|
78
|
+
let m;
|
|
79
|
+
while ((m = enumPattern.exec(content)) !== null) {
|
|
80
|
+
const enumName = m[1];
|
|
81
|
+
const body = m[2];
|
|
82
|
+
const memberPattern = /([A-Za-z_$][A-Za-z0-9_$]*)\s*=\s*['"`]([^'"`\n]+)['"`]/g;
|
|
83
|
+
let mm;
|
|
84
|
+
while ((mm = memberPattern.exec(body)) !== null) {
|
|
85
|
+
result[`${enumName}.${mm[1]}`] = mm[2];
|
|
86
|
+
result[mm[1]] = mm[2];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Extract all enum values from Java source.
|
|
93
|
+
* Supports constructor-style enums: MEMBER("value")
|
|
94
|
+
*/
|
|
95
|
+
function extractJavaEnumValues(content) {
|
|
96
|
+
const result = {};
|
|
97
|
+
// Allow {param} segments inside enum body strings (e.g. "/users/{id}")
|
|
98
|
+
const enumBlock = /enum\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?:implements[^{]*)?\{((?:[^{}]|\{[^}]*\})*)\}/gs;
|
|
99
|
+
let m;
|
|
100
|
+
while ((m = enumBlock.exec(content)) !== null) {
|
|
101
|
+
const enumName = m[1];
|
|
102
|
+
const body = m[2];
|
|
103
|
+
const memberPattern = /([A-Z_][A-Z0-9_]*)\s*\(\s*"([^"]+)"/g;
|
|
104
|
+
let mm;
|
|
105
|
+
while ((mm = memberPattern.exec(body)) !== null) {
|
|
106
|
+
result[`${enumName}.${mm[1]}`] = mm[2];
|
|
107
|
+
result[mm[1]] = mm[2];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Extract all enum values from Kotlin source.
|
|
114
|
+
*/
|
|
115
|
+
function extractKotlinEnumValues(content) {
|
|
116
|
+
const result = {};
|
|
117
|
+
const enumBlock = /enum\s+class\s+([A-Za-z_][A-Za-z0-9_]*)[^{]*\{([^}]+)\}/gs;
|
|
118
|
+
let m;
|
|
119
|
+
while ((m = enumBlock.exec(content)) !== null) {
|
|
120
|
+
const enumName = m[1];
|
|
121
|
+
const body = m[2];
|
|
122
|
+
const memberPattern = /([A-Z_][A-Z0-9_]*)\s*\(\s*["']([^"']+)["']/g;
|
|
123
|
+
let mm;
|
|
124
|
+
while ((mm = memberPattern.exec(body)) !== null) {
|
|
125
|
+
result[`${enumName}.${mm[1]}`] = mm[2];
|
|
126
|
+
result[mm[1]] = mm[2];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Extract all enum values from Python source.
|
|
133
|
+
* Supports class Routes(Enum): MEMBER = "value"
|
|
134
|
+
*/
|
|
135
|
+
function extractPythonEnumValues(content) {
|
|
136
|
+
const result = {};
|
|
137
|
+
// Note: no \s* after colon — the \n must be left for the body group to match
|
|
138
|
+
// Use [ \t]* (not \s*) for trailing whitespace to avoid consuming next line's \n
|
|
139
|
+
const enumBlock = /class\s+([A-Za-z_][A-Za-z0-9_]*)\s*\([^)]*Enum[^)]*\):((?:\n[ \t]+[A-Z_][A-Z0-9_]*\s*=\s*['"][^'"]+['"][ \t]*)+)/g;
|
|
140
|
+
let m;
|
|
141
|
+
while ((m = enumBlock.exec(content)) !== null) {
|
|
142
|
+
const enumName = m[1];
|
|
143
|
+
const body = m[2];
|
|
144
|
+
const memberPattern = /([A-Z_][A-Z0-9_]*)\s*=\s*['"]([^'"]+)['"]/g;
|
|
145
|
+
let mm;
|
|
146
|
+
while ((mm = memberPattern.exec(body)) !== null) {
|
|
147
|
+
result[`${enumName}.${mm[1]}`] = mm[2];
|
|
148
|
+
result[mm[1]] = mm[2];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep Code Analysis — Method Chain Resolution
|
|
3
|
+
*
|
|
4
|
+
* Traces method calls to helper/wrapper functions within the same file,
|
|
5
|
+
* following the call graph up to a configurable depth.
|
|
6
|
+
*
|
|
7
|
+
* Also detects builder-style method chains that resolve to HTTP calls.
|
|
8
|
+
*
|
|
9
|
+
* Supported patterns:
|
|
10
|
+
*
|
|
11
|
+
* TypeScript/JavaScript:
|
|
12
|
+
* function getUsers(client) { return client.get('/users'); }
|
|
13
|
+
* getUsers(apiClient); → GET /users
|
|
14
|
+
*
|
|
15
|
+
* Java:
|
|
16
|
+
* private Response fetchUser(String id) { return api.get("/users/" + id); }
|
|
17
|
+
* fetchUser(userId); → GET /users/{id}
|
|
18
|
+
*
|
|
19
|
+
* Python:
|
|
20
|
+
* def fetch_customer(customer_id): return client.get(build_path(customer_id))
|
|
21
|
+
*/
|
|
22
|
+
import type { CallGraph, ResolvedHttpCall } from './types';
|
|
23
|
+
import type { SymbolTable } from './types';
|
|
24
|
+
/**
|
|
25
|
+
* Given a function call expression like `getUsers(apiClient)`, look up the
|
|
26
|
+
* callee in the call graph, recurse into its body (up to maxDepth), and return
|
|
27
|
+
* any HTTP calls found inside.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveWrapperCall(callee: string, graph: CallGraph, table: SymbolTable, sourceFile: string, sourceLanguage: string, maxDepth: number, currentDepth?: number): ResolvedHttpCall[];
|
|
30
|
+
/**
|
|
31
|
+
* Resolve the path returned by a helper function when it is passed as the
|
|
32
|
+
* argument to an HTTP call.
|
|
33
|
+
*
|
|
34
|
+
* Example: client.get(getUserPath(userId))
|
|
35
|
+
* → getUserPath is in the call graph, returns `/users/${userId}`
|
|
36
|
+
* → normalized: /users/{id}
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveHelperReturnPath(calleeName: string, graph: CallGraph, table: SymbolTable, maxDepth: number, currentDepth?: number): string | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Detect calls to local helper functions inside HTTP call argument positions
|
|
41
|
+
* in Python source.
|
|
42
|
+
*
|
|
43
|
+
* Example:
|
|
44
|
+
* client.get(build_customer_path(customer_id))
|
|
45
|
+
* → extracts 'build_customer_path' as a path-builder call
|
|
46
|
+
*/
|
|
47
|
+
export declare function extractPythonHelperCallsInHttpArgs(content: string): Array<{
|
|
48
|
+
method: string;
|
|
49
|
+
helperName: string;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Detect calls to local helper functions inside HTTP call argument positions
|
|
53
|
+
* in TypeScript/JavaScript source.
|
|
54
|
+
*
|
|
55
|
+
* Example:
|
|
56
|
+
* client.get(getUserPath(userId))
|
|
57
|
+
*/
|
|
58
|
+
export declare function extractJsHelperCallsInHttpArgs(content: string): Array<{
|
|
59
|
+
method: string;
|
|
60
|
+
helperName: string;
|
|
61
|
+
}>;
|
|
62
|
+
/**
|
|
63
|
+
* Detect calls to local helper functions inside HTTP call argument positions
|
|
64
|
+
* in Java/Kotlin source.
|
|
65
|
+
*/
|
|
66
|
+
export declare function extractJavaHelperCallsInHttpArgs(content: string): Array<{
|
|
67
|
+
method: string;
|
|
68
|
+
helperName: string;
|
|
69
|
+
}>;
|
|
70
|
+
//# sourceMappingURL=resolveMethodChains.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveMethodChains.d.ts","sourceRoot":"","sources":["../../../../src/coverage/deep-analysis/resolveMethodChains.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAK3C;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,EAChB,YAAY,SAAI,GACf,gBAAgB,EAAE,CA4CpB;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,MAAM,EAChB,YAAY,SAAI,GACf,MAAM,GAAG,SAAS,CAyBpB;AAID;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,MAAM,GACd,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAY/C;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,MAAM,GACd,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAW/C;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,MAAM,GACd,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAY/C"}
|