@gnapi/cotester 1.2.6 → 1.2.8
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/analyzer.d.ts +10 -0
- package/dist/analyzer.js +65 -0
- package/dist/analyzer.js.map +1 -1
- package/dist/astCache.js +1 -1
- package/dist/astCache.js.map +1 -1
- package/dist/auditLogger.d.ts +2 -0
- package/dist/auditLogger.js +38 -0
- package/dist/auditLogger.js.map +1 -1
- package/dist/branchAnalyzer.d.ts +1 -1
- package/dist/branchAnalyzer.js +91 -18
- package/dist/branchAnalyzer.js.map +1 -1
- package/dist/checker.d.ts +13 -0
- package/dist/checker.js +76 -1
- package/dist/checker.js.map +1 -1
- package/dist/cli.js +26 -4
- package/dist/cli.js.map +1 -1
- package/dist/configManager.d.ts +6 -0
- package/dist/configManager.js +44 -0
- package/dist/configManager.js.map +1 -1
- package/dist/frameworkAdapter.d.ts +19 -0
- package/dist/frameworkAdapter.js +30 -1
- package/dist/frameworkAdapter.js.map +1 -1
- package/dist/generator.js +149 -37
- package/dist/generator.js.map +1 -1
- package/dist/ignoreManager.js +10 -1
- package/dist/ignoreManager.js.map +1 -1
- package/dist/interfaceShapeResolver.js +77 -41
- package/dist/interfaceShapeResolver.js.map +1 -1
- package/dist/mockDataEngine.js +132 -1
- package/dist/mockDataEngine.js.map +1 -1
- package/dist/mockGenerator.js +4 -1
- package/dist/mockGenerator.js.map +1 -1
- package/dist/ormMockGenerator.js +77 -8
- package/dist/ormMockGenerator.js.map +1 -1
- package/dist/reporter.d.ts +1 -1
- package/dist/reporter.js +116 -4
- package/dist/reporter.js.map +1 -1
- package/dist/scenarioEngine.d.ts +3 -0
- package/dist/scenarioEngine.js +76 -1
- package/dist/scenarioEngine.js.map +1 -1
- package/dist/validator.d.ts +25 -0
- package/dist/validator.js +171 -0
- package/dist/validator.js.map +1 -0
- package/dist/watcher.js +30 -1
- package/dist/watcher.js.map +1 -1
- package/package.json +1 -1
package/dist/analyzer.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ import { PathAliases } from "./pathAliasResolver";
|
|
|
4
4
|
export interface ParameterMeta {
|
|
5
5
|
name: string;
|
|
6
6
|
type: string;
|
|
7
|
+
/** true when the parameter is optional (declared with `?` or has a default value) */
|
|
8
|
+
isOptional?: boolean;
|
|
7
9
|
}
|
|
8
10
|
/** Per-function return type metadata for a single imported name */
|
|
9
11
|
export interface ImportedFunctionMeta {
|
|
@@ -33,6 +35,8 @@ export interface DependencyMeta {
|
|
|
33
35
|
export interface FunctionMeta {
|
|
34
36
|
name: string;
|
|
35
37
|
className?: string;
|
|
38
|
+
/** true when this is a static class method */
|
|
39
|
+
isStatic?: boolean;
|
|
36
40
|
parameters: ParameterMeta[];
|
|
37
41
|
returnType: string;
|
|
38
42
|
/** Function uses async/await or returns a Promise */
|
|
@@ -51,6 +55,12 @@ export interface FunctionMeta {
|
|
|
51
55
|
ormUsage: OrmUsage | null;
|
|
52
56
|
/** Absolute path of the source file containing this function (for interface shape resolution) */
|
|
53
57
|
sourceFilePath: string;
|
|
58
|
+
/** 1-based line number where this function starts (for LCOV FN: records) */
|
|
59
|
+
lineNumber?: number;
|
|
60
|
+
/** true when the containing class is decorated with a NestJS @Injectable / @Controller / @Resolver */
|
|
61
|
+
isNestInjectable?: boolean;
|
|
62
|
+
/** Decorator names found on the containing class (e.g. ['Injectable', 'Controller']) */
|
|
63
|
+
classDecorators?: string[];
|
|
54
64
|
}
|
|
55
65
|
/** Detected structural file type */
|
|
56
66
|
export type FileType = "controller" | "service" | "repository" | "unknown";
|
package/dist/analyzer.js
CHANGED
|
@@ -62,12 +62,16 @@ function analyzeFile(filePath, aliases) {
|
|
|
62
62
|
for (const fn of functions) {
|
|
63
63
|
if (!fn.isExported())
|
|
64
64
|
continue;
|
|
65
|
+
// Skip overload signatures (they have no body)
|
|
66
|
+
if (fn.getBody() === undefined)
|
|
67
|
+
continue;
|
|
65
68
|
const name = fn.getName();
|
|
66
69
|
if (!name)
|
|
67
70
|
continue;
|
|
68
71
|
const parameters = fn.getParameters().map((p) => ({
|
|
69
72
|
name: p.getName(),
|
|
70
73
|
type: p.getType().getText(p) || "unknown",
|
|
74
|
+
isOptional: p.isOptional(),
|
|
71
75
|
}));
|
|
72
76
|
const returnType = fn.getReturnType().getText(fn) || "void";
|
|
73
77
|
const isAsync = fn.isAsync() || returnType.toLowerCase().startsWith("promise");
|
|
@@ -86,14 +90,63 @@ function analyzeFile(filePath, aliases) {
|
|
|
86
90
|
fileType,
|
|
87
91
|
ormUsage,
|
|
88
92
|
sourceFilePath: filePath,
|
|
93
|
+
lineNumber: fn.getStartLineNumber(),
|
|
89
94
|
});
|
|
90
95
|
}
|
|
96
|
+
// ── Exported arrow functions / function expressions (variable statements) ──
|
|
97
|
+
const NEST_DECORATORS = ["Injectable", "Controller", "Resolver", "Module", "Guard", "Interceptor", "Pipe", "Middleware"];
|
|
98
|
+
for (const stmt of sourceFile.getVariableStatements()) {
|
|
99
|
+
if (!stmt.isExported())
|
|
100
|
+
continue;
|
|
101
|
+
for (const decl of stmt.getDeclarations()) {
|
|
102
|
+
const init = decl.getInitializer();
|
|
103
|
+
if (!init)
|
|
104
|
+
continue;
|
|
105
|
+
const kind = init.getKind();
|
|
106
|
+
if (kind !== ts_morph_1.SyntaxKind.ArrowFunction && kind !== ts_morph_1.SyntaxKind.FunctionExpression)
|
|
107
|
+
continue;
|
|
108
|
+
const name = decl.getName();
|
|
109
|
+
if (!name)
|
|
110
|
+
continue;
|
|
111
|
+
const fnNode = init;
|
|
112
|
+
const parameters = fnNode.getParameters().map((p) => ({
|
|
113
|
+
name: p.getName(),
|
|
114
|
+
type: p.getType().getText(p) || "unknown",
|
|
115
|
+
isOptional: p.isOptional(),
|
|
116
|
+
}));
|
|
117
|
+
const returnType = fnNode.getReturnType().getText(fnNode) || "void";
|
|
118
|
+
const isAsync = fnNode.isAsync?.() || returnType.toLowerCase().startsWith("promise");
|
|
119
|
+
const throwsErrors = bodyContainsThrow(fnNode);
|
|
120
|
+
const dependencies = findUsedDependencies(fnNode, fileImports, sourceFile);
|
|
121
|
+
const branches = (0, branchAnalyzer_1.analyzeBranches)(fnNode);
|
|
122
|
+
const ormUsage = (0, ormMockGenerator_1.detectOrmUsage)(fnNode);
|
|
123
|
+
results.push({
|
|
124
|
+
name,
|
|
125
|
+
parameters,
|
|
126
|
+
returnType,
|
|
127
|
+
isAsync,
|
|
128
|
+
throwsErrors,
|
|
129
|
+
dependencies,
|
|
130
|
+
branches,
|
|
131
|
+
fileType,
|
|
132
|
+
ormUsage,
|
|
133
|
+
sourceFilePath: filePath,
|
|
134
|
+
lineNumber: decl.getStartLineNumber(),
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
91
138
|
// ── Exported class declarations → public methods ────────────────────
|
|
92
139
|
const classes = sourceFile.getClasses();
|
|
93
140
|
for (const cls of classes) {
|
|
94
141
|
if (!cls.isExported())
|
|
95
142
|
continue;
|
|
143
|
+
// Skip abstract classes — they can't be instantiated directly
|
|
144
|
+
if (cls.isAbstract())
|
|
145
|
+
continue;
|
|
96
146
|
const className = cls.getName() ?? "AnonymousClass";
|
|
147
|
+
// Detect NestJS DI decorators for specialized mock generation
|
|
148
|
+
const classDecoratorNames = cls.getDecorators().map((d) => d.getName());
|
|
149
|
+
const isNestInjectable = classDecoratorNames.some((n) => NEST_DECORATORS.includes(n));
|
|
97
150
|
// Extract constructor params for DI
|
|
98
151
|
const constructorParams = extractConstructorParams(cls);
|
|
99
152
|
const methods = cls.getMethods();
|
|
@@ -103,13 +156,21 @@ function analyzeFile(filePath, aliases) {
|
|
|
103
156
|
method.hasModifier(ts_morph_1.SyntaxKind.ProtectedKeyword)) {
|
|
104
157
|
continue;
|
|
105
158
|
}
|
|
159
|
+
// Skip abstract methods — no implementation to test
|
|
160
|
+
if (method.isAbstract())
|
|
161
|
+
continue;
|
|
162
|
+
// Skip overload signatures (no body)
|
|
163
|
+
if (method.getBody() === undefined)
|
|
164
|
+
continue;
|
|
106
165
|
const name = method.getName();
|
|
107
166
|
const parameters = method.getParameters().map((p) => ({
|
|
108
167
|
name: p.getName(),
|
|
109
168
|
type: p.getType().getText(p) || "unknown",
|
|
169
|
+
isOptional: p.isOptional(),
|
|
110
170
|
}));
|
|
111
171
|
const returnType = method.getReturnType().getText(method) || "void";
|
|
112
172
|
const isAsync = method.isAsync() || returnType.toLowerCase().startsWith("promise");
|
|
173
|
+
const isStatic = method.hasModifier(ts_morph_1.SyntaxKind.StaticKeyword);
|
|
113
174
|
const throwsErrors = bodyContainsThrow(method);
|
|
114
175
|
const dependencies = findUsedDependencies(method, fileImports, sourceFile);
|
|
115
176
|
const branches = (0, branchAnalyzer_1.analyzeBranches)(method);
|
|
@@ -117,6 +178,7 @@ function analyzeFile(filePath, aliases) {
|
|
|
117
178
|
results.push({
|
|
118
179
|
name,
|
|
119
180
|
className,
|
|
181
|
+
isStatic,
|
|
120
182
|
parameters,
|
|
121
183
|
returnType,
|
|
122
184
|
isAsync,
|
|
@@ -127,6 +189,9 @@ function analyzeFile(filePath, aliases) {
|
|
|
127
189
|
fileType,
|
|
128
190
|
ormUsage,
|
|
129
191
|
sourceFilePath: filePath,
|
|
192
|
+
lineNumber: method.getStartLineNumber(),
|
|
193
|
+
isNestInjectable,
|
|
194
|
+
classDecorators: classDecoratorNames,
|
|
130
195
|
});
|
|
131
196
|
}
|
|
132
197
|
}
|
package/dist/analyzer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoFA,kCAoKC;AAxPD,uCAAiE;AACjE,2CAA6B;AAC7B,qDAA+D;AAC/D,yDAA8D;AAC9D,2DAAgE;AAqEhE,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,SAAgB,WAAW,CAAC,QAAgB,EAAE,OAAqB;IAC/D,MAAM,OAAO,GAAG,IAAI,kBAAO,CAAC,EAAE,eAAe,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IACpE,MAAM,UAAU,GAAe,OAAO,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAErE,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAE1C,mEAAmE;IACnE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,cAAc,CAAC,UAAU,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAEnE,uEAAuE;IACvE,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,EAAE,CAAC;IAC5C,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE;YAAE,SAAS;QAE/B,+CAA+C;QAC/C,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,SAAS;YAAE,SAAS;QAEzC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,MAAM,UAAU,GAAoB,EAAE,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/D,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;YACjB,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,SAAS;YACzC,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE;SAC7B,CAAC,CAAC,CAAC;QAEJ,MAAM,UAAU,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC;QAC5D,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC/E,MAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,oBAAoB,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;QACvE,MAAM,QAAQ,GAAG,IAAA,gCAAe,EAAC,EAAE,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAA,iCAAc,EAAC,EAAE,CAAC,CAAC;QAEpC,OAAO,CAAC,IAAI,CAAC;YACT,IAAI;YACJ,UAAU;YACV,UAAU;YACV,OAAO;YACP,YAAY;YACZ,YAAY;YACZ,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,cAAc,EAAE,QAAQ;YACxB,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE;SACtC,CAAC,CAAC;IACP,CAAC;IAED,8EAA8E;IAC9E,MAAM,eAAe,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IACzH,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,qBAAqB,EAAE,EAAE,CAAC;QACpD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YAAE,SAAS;QAEjC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACnC,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC5B,IAAI,IAAI,KAAK,qBAAU,CAAC,aAAa,IAAI,IAAI,KAAK,qBAAU,CAAC,kBAAkB;gBAAE,SAAS;YAE1F,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,MAAM,MAAM,GAAG,IAAgF,CAAC;YAChG,MAAM,UAAU,GAAoB,MAAM,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACnE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;gBACjB,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,SAAS;gBACzC,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE;aAC7B,CAAC,CAAC,CAAC;YAEJ,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;YACpE,MAAM,OAAO,GAAI,MAAc,CAAC,OAAO,EAAE,EAAE,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAC9F,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,YAAY,GAAG,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;YAC3E,MAAM,QAAQ,GAAG,IAAA,gCAAe,EAAC,MAAM,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,IAAA,iCAAc,EAAC,MAAM,CAAC,CAAC;YAExC,OAAO,CAAC,IAAI,CAAC;gBACT,IAAI;gBACJ,UAAU;gBACV,UAAU;gBACV,OAAO;gBACP,YAAY;gBACZ,YAAY;gBACZ,QAAQ;gBACR,QAAQ;gBACR,QAAQ;gBACR,cAAc,EAAE,QAAQ;gBACxB,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE;aACxC,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,uEAAuE;IACvE,MAAM,OAAO,GAAG,UAAU,CAAC,UAAU,EAAE,CAAC;IACxC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE;YAAE,SAAS;QAEhC,8DAA8D;QAC9D,IAAI,GAAG,CAAC,UAAU,EAAE;YAAE,SAAS;QAE/B,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,EAAE,IAAI,gBAAgB,CAAC;QAEpD,8DAA8D;QAC9D,MAAM,mBAAmB,GAAG,GAAG,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACxE,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAEtF,oCAAoC;QACpC,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;QAExD,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QACjC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC3B,2BAA2B;YAC3B,IACI,MAAM,CAAC,WAAW,CAAC,qBAAU,CAAC,cAAc,CAAC;gBAC7C,MAAM,CAAC,WAAW,CAAC,qBAAU,CAAC,gBAAgB,CAAC,EACjD,CAAC;gBACC,SAAS;YACb,CAAC;YAED,oDAAoD;YACpD,IAAI,MAAM,CAAC,UAAU,EAAE;gBAAE,SAAS;YAElC,qCAAqC;YACrC,IAAI,MAAM,CAAC,OAAO,EAAE,KAAK,SAAS;gBAAE,SAAS;YAE7C,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAoB,MAAM,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACnE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;gBACjB,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,SAAS;gBACzC,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE;aAC7B,CAAC,CAAC,CAAC;YAEJ,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;YACpE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YACnF,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,qBAAU,CAAC,aAAa,CAAC,CAAC;YAC9D,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,YAAY,GAAG,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;YAC3E,MAAM,QAAQ,GAAG,IAAA,gCAAe,EAAC,MAAM,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,IAAA,iCAAc,EAAC,MAAM,CAAC,CAAC;YAExC,OAAO,CAAC,IAAI,CAAC;gBACT,IAAI;gBACJ,SAAS;gBACT,QAAQ;gBACR,UAAU;gBACV,UAAU;gBACV,OAAO;gBACP,YAAY;gBACZ,YAAY;gBACZ,iBAAiB;gBACjB,QAAQ;gBACR,QAAQ;gBACR,QAAQ;gBACR,cAAc,EAAE,QAAQ;gBACxB,UAAU,EAAE,MAAM,CAAC,kBAAkB,EAAE;gBACvC,gBAAgB;gBAChB,eAAe,EAAE,mBAAmB;aACvC,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAWD,SAAS,cAAc,CACnB,UAAsB,EACtB,OAAqB,EACrB,SAAkB;IAElB,MAAM,OAAO,GAAiB,EAAE,CAAC;IAEjC,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,qBAAqB,EAAE,EAAE,CAAC;QACpD,IAAI,UAAU,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAEhD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7D,qDAAqD;YACrD,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;gBACvB,MAAM,QAAQ,GAAG,IAAA,gCAAY,EAAC,UAAU,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;gBAC9D,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;oBACpB,UAAU,GAAG,QAAQ,CAAC;gBAC1B,CAAC;qBAAM,CAAC;oBACJ,wDAAwD;oBACxD,SAAS;gBACb,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,SAAS;YACb,CAAC;QACL,CAAC;QAED,iFAAiF;QACjF,IAAI,IAAI,CAAC,UAAU,EAAE;YAAE,SAAS;QAEhC,iBAAiB;QACjB,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9C,IAAI,aAAa,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC;gBACT,UAAU;gBACV,SAAS,EAAE,aAAa,CAAC,OAAO,EAAE;gBAClC,YAAY,EAAE,SAAS;gBACvB,SAAS,EAAE,IAAI;aAClB,CAAC,CAAC;QACP,CAAC;QAED,gBAAgB;QAChB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YACzC,oEAAoE;YACpE,IAAI,KAAK,CAAC,UAAU,EAAE;gBAAE,SAAS;YAEjC,2EAA2E;YAC3E,yEAAyE;YACzE,sEAAsE;YACtE,IAAI,CAAC;gBACD,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,CAAC;gBAC5C,MAAM,KAAK,GAAG,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;gBAC3C,IACI,KAAK,CAAC,MAAM,GAAG,CAAC;oBAChB,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;wBACd,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;wBACtB,OAAO,CACH,CAAC,KAAK,qBAAU,CAAC,oBAAoB;4BACrC,CAAC,KAAK,qBAAU,CAAC,oBAAoB,CACxC,CAAC;oBACN,CAAC,CAAC,EACJ,CAAC;oBACC,SAAS,CAAC,yCAAyC;gBACvD,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACL,+DAA+D;YACnE,CAAC;YAED,OAAO,CAAC,IAAI,CAAC;gBACT,UAAU;gBACV,SAAS,EAAE,KAAK,CAAC,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,KAAK,CAAC,OAAO,EAAE;gBAC7D,YAAY,EAAE,KAAK,CAAC,OAAO,EAAE;gBAC7B,SAAS,EAAE,KAAK;aACnB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,gFAAgF;AAEhF,SAAS,oBAAoB,CACzB,MAAY,EACZ,WAAyB,EACzB,UAAsB;IAEtB,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IAEjD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC5B,0DAA0D;QAC1D,sDAAsD;QACtD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,MAAM,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAChE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC5C,IAAI,QAAQ,EAAE,CAAC;gBACX,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;oBACrD,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;gBAClD,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE;oBACvB,UAAU,EAAE,GAAG,CAAC,UAAU;oBAC1B,aAAa,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC;oBACjC,SAAS,EAAE,GAAG,CAAC,SAAS;oBACxB,SAAS,EAAE,GAAG,CAAC,SAAS;oBACxB,oBAAoB,EAAE,EAAE;iBAC3B,CAAC,CAAC;YACP,CAAC;QACL,CAAC;IACL,CAAC;IAED,gFAAgF;IAChF,oFAAoF;IACpF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QAChC,GAAG,CAAC,oBAAoB,GAAG,2BAA2B,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,SAAS,2BAA2B,CAChC,UAAsB,EACtB,GAAmB;IAEnB,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,IAAI,CAAC;QACD,MAAM,UAAU,GAAG,UAAU,CAAC,oBAAoB,CAC9C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,uBAAuB,EAAE,KAAK,GAAG,CAAC,UAAU,CACxD,CAAC;QACF,IAAI,CAAC,UAAU;YAAE,OAAO,MAAM,CAAC;QAE/B,KAAK,MAAM,YAAY,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;YAC3C,IAAI,YAAY,KAAK,SAAS;gBAAE,SAAS;YAEzC,MAAM,WAAW,GAAG,UAAU;iBACzB,eAAe,EAAE;iBACjB,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,YAAY,CAAC,CAAC;YAC/C,IAAI,CAAC,WAAW;gBAAE,SAAS;YAE3B,MAAM,IAAI,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,CAAC;YACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC1C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAEpC,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,cAAc,GAAG,GAAG,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,CAAC;YACrD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC3C,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;gBACjB,IAAI,EAAE,CAAC,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,IAAI,SAAS;aAChE,CAAC,CAAC,CAAC;YACJ,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACrF,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,6EAA6E;IACjF,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC5B,OAAO,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACtD,CAAC;AAED,gFAAgF;AAEhF,SAAS,iBAAiB,CAAC,IAAU;IACjC,OAAO,IAAI,CAAC,oBAAoB,CAAC,qBAAU,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AAC3E,CAAC;AAED,gFAAgF;AAEhF,SAAS,wBAAwB,CAAC,GAAQ;IACtC,MAAM,KAAK,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC;IACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;QACzC,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;QACjB,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,SAAS;KAC5C,CAAC,CAAC,CAAC;AACR,CAAC;AAED,gFAAgF;AAEhF,SAAS,cAAc,CAAC,QAAgB;IACpC,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IACrE,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAErC,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,YAAY,CAAC;IACtD,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAChD,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,YAAY,CAAC;IAEhF,OAAO,SAAS,CAAC;AACrB,CAAC"}
|
package/dist/astCache.js
CHANGED
|
@@ -63,7 +63,7 @@ const pathAliasResolver_1 = require("./pathAliasResolver");
|
|
|
63
63
|
* Increment when FunctionMeta or any nested type (BranchInfo, OrmUsage, …)
|
|
64
64
|
* changes shape. Old on-disk entries with a different version are discarded.
|
|
65
65
|
*/
|
|
66
|
-
const CACHE_VERSION = "
|
|
66
|
+
const CACHE_VERSION = "3"; // bumped: added lineNumber, classDecorators, isNestInjectable to FunctionMeta
|
|
67
67
|
/**
|
|
68
68
|
* In-process cache. Shared within a single watcher/worker process lifetime.
|
|
69
69
|
* Prevents redundant disk reads on rapid successive saves of the same file.
|
package/dist/astCache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"astCache.js","sourceRoot":"","sources":["../src/astCache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4GA,8CA8CC;AAMD,oDAcC;AAMD,4CAGC;AAvLD;;;;;;;;;;;;;;;;GAgBG;AACH,mCAAoC;AACpC,uCAAyB;AACzB,2CAA6B;AAC7B,yCAAuD;AACvD,2DAAmE;AAanE,iFAAiF;AAEjF;;;GAGG;AACH,MAAM,aAAa,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"astCache.js","sourceRoot":"","sources":["../src/astCache.ts"],"names":[],"mappings":"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"}
|
package/dist/auditLogger.d.ts
CHANGED
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
export interface AuditEntry {
|
|
18
18
|
/** ISO-8601 UTC timestamp of the generation run */
|
|
19
19
|
timestamp: string;
|
|
20
|
+
/** L-4: IANA timezone name so compliance tools can distinguish UTC vs local time */
|
|
21
|
+
timezone: string;
|
|
20
22
|
/** Source file path relative to projectRoot, forward-slash separated */
|
|
21
23
|
file: string;
|
|
22
24
|
/** Function/method names for which a new describe block was written */
|
package/dist/auditLogger.js
CHANGED
|
@@ -56,6 +56,9 @@ const path = __importStar(require("path"));
|
|
|
56
56
|
const utils_1 = require("./utils");
|
|
57
57
|
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
58
58
|
const AUDIT_FILE = path.join("cotester", ".audit.jsonl");
|
|
59
|
+
/** H-6: rotate the log when it exceeds 50 MB or 10 000 entries */
|
|
60
|
+
const MAX_AUDIT_BYTES = 50 * 1024 * 1024; // 50 MB
|
|
61
|
+
const MAX_AUDIT_LINES = 10000;
|
|
59
62
|
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
60
63
|
/**
|
|
61
64
|
* Append one audit entry to `cotester/.audit.jsonl`.
|
|
@@ -79,6 +82,8 @@ function writeAuditEntry(entry, projectRoot, dryRun = false) {
|
|
|
79
82
|
const auditPath = path.join(projectRoot, AUDIT_FILE);
|
|
80
83
|
(0, utils_1.ensureDir)(path.dirname(auditPath));
|
|
81
84
|
try {
|
|
85
|
+
// H-6: rotate log when it exceeds size or line count limits
|
|
86
|
+
rotateAuditLogIfNeeded(auditPath);
|
|
82
87
|
fs.appendFileSync(auditPath, line + "\n", "utf-8");
|
|
83
88
|
}
|
|
84
89
|
catch (err) {
|
|
@@ -96,12 +101,45 @@ function writeAuditEntry(entry, projectRoot, dryRun = false) {
|
|
|
96
101
|
* @param skipped Function names already covered with no changes.
|
|
97
102
|
*/
|
|
98
103
|
function buildAuditEntry(srcFilePath, projectRoot, added, merged, skipped) {
|
|
104
|
+
// L-4: include IANA timezone so compliance tools can distinguish UTC vs local
|
|
105
|
+
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone ?? "UTC";
|
|
99
106
|
return {
|
|
100
107
|
timestamp: new Date().toISOString(),
|
|
108
|
+
timezone,
|
|
101
109
|
file: path.relative(projectRoot, srcFilePath).replace(/\\/g, "/"),
|
|
102
110
|
added,
|
|
103
111
|
merged,
|
|
104
112
|
skipped,
|
|
105
113
|
};
|
|
106
114
|
}
|
|
115
|
+
// ─── H-6: Log rotation ────────────────────────────────────────────────────────
|
|
116
|
+
/**
|
|
117
|
+
* Rotate `auditPath` to `auditPath.1` when it exceeds MAX_AUDIT_BYTES or
|
|
118
|
+
* MAX_AUDIT_LINES. Keeps at most one rotated archive (`.audit.jsonl.1`).
|
|
119
|
+
*/
|
|
120
|
+
function rotateAuditLogIfNeeded(auditPath) {
|
|
121
|
+
try {
|
|
122
|
+
if (!fs.existsSync(auditPath))
|
|
123
|
+
return;
|
|
124
|
+
const stat = fs.statSync(auditPath);
|
|
125
|
+
let needsRotation = stat.size >= MAX_AUDIT_BYTES;
|
|
126
|
+
if (!needsRotation) {
|
|
127
|
+
// Check line count without reading the whole file — count newlines
|
|
128
|
+
const content = fs.readFileSync(auditPath, "utf-8");
|
|
129
|
+
const lineCount = (content.match(/\n/g) ?? []).length;
|
|
130
|
+
needsRotation = lineCount >= MAX_AUDIT_LINES;
|
|
131
|
+
}
|
|
132
|
+
if (needsRotation) {
|
|
133
|
+
const archivePath = auditPath + ".1";
|
|
134
|
+
// Overwrite previous archive if it exists
|
|
135
|
+
if (fs.existsSync(archivePath))
|
|
136
|
+
fs.unlinkSync(archivePath);
|
|
137
|
+
fs.renameSync(auditPath, archivePath);
|
|
138
|
+
(0, utils_1.log)(`Audit log rotated → ${path.basename(archivePath)}`, "info");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// Non-fatal — rotation failure should not block writes
|
|
143
|
+
}
|
|
144
|
+
}
|
|
107
145
|
//# sourceMappingURL=auditLogger.js.map
|
package/dist/auditLogger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auditLogger.js","sourceRoot":"","sources":["../src/auditLogger.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"auditLogger.js","sourceRoot":"","sources":["../src/auditLogger.ts"],"names":[],"mappings":"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"}
|
package/dist/branchAnalyzer.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface BranchInfo {
|
|
|
7
7
|
/** Suggested test label for the "false" path */
|
|
8
8
|
falseLabel: string;
|
|
9
9
|
/** Type of branch */
|
|
10
|
-
kind: "if" | "ternary" | "guard" | "nullcheck" | "logical";
|
|
10
|
+
kind: "if" | "ternary" | "guard" | "nullcheck" | "logical" | "optionalchain" | "nullish" | "switch" | "trycatch";
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* Analyze a function/method body for conditional branches.
|
package/dist/branchAnalyzer.js
CHANGED
|
@@ -44,26 +44,97 @@ function analyzeBranches(fnNode) {
|
|
|
44
44
|
const binaryExpressions = fnNode.getDescendantsOfKind(ts_morph_1.SyntaxKind.BinaryExpression);
|
|
45
45
|
for (const bin of binaryExpressions) {
|
|
46
46
|
const opToken = bin.getOperatorToken().getText();
|
|
47
|
-
if (opToken
|
|
47
|
+
if (opToken === "&&" || opToken === "||") {
|
|
48
|
+
// skip if already captured as part of an if condition
|
|
49
|
+
const parent = bin.getParent();
|
|
50
|
+
if (parent?.getKind() === ts_morph_1.SyntaxKind.IfStatement)
|
|
51
|
+
continue;
|
|
52
|
+
if (parent?.getKind() === ts_morph_1.SyntaxKind.ParenthesizedExpression) {
|
|
53
|
+
const grandparent = parent.getParent();
|
|
54
|
+
if (grandparent?.getKind() === ts_morph_1.SyntaxKind.IfStatement)
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const condText = bin.getText().trim();
|
|
58
|
+
if (seen.has(condText) || condText.length > 80)
|
|
59
|
+
continue;
|
|
60
|
+
seen.add(condText);
|
|
61
|
+
branches.push({
|
|
62
|
+
condition: condText,
|
|
63
|
+
trueLabel: `handles case when ${simplifyCondition(condText)}`,
|
|
64
|
+
falseLabel: `handles case when ${negateSimple(condText)}`,
|
|
65
|
+
kind: "logical",
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
else if (opToken === "??") {
|
|
69
|
+
// Nullish coalescing — two paths: left is null/undefined, left has value
|
|
70
|
+
const leftText = bin.getLeft().getText().trim();
|
|
71
|
+
const key = `??:${leftText}`;
|
|
72
|
+
if (seen.has(key))
|
|
73
|
+
continue;
|
|
74
|
+
seen.add(key);
|
|
75
|
+
branches.push({
|
|
76
|
+
condition: `${leftText} ?? ...`,
|
|
77
|
+
trueLabel: `uses fallback when ${simplifyCondition(leftText)} is null/undefined`,
|
|
78
|
+
falseLabel: `uses ${simplifyCondition(leftText)} value when defined`,
|
|
79
|
+
kind: "nullish",
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// ── Optional chaining (?.) ────────────────────────────────────────────
|
|
84
|
+
// Use PropertyAccessExpression and check for question-dot token via getText
|
|
85
|
+
const propAccesses = fnNode.getDescendantsOfKind(ts_morph_1.SyntaxKind.PropertyAccessExpression);
|
|
86
|
+
for (const pa of propAccesses) {
|
|
87
|
+
// ts-morph: hasQuestionDotToken() available on PropertyAccessExpression
|
|
88
|
+
const hasQD = pa.hasQuestionDotToken?.();
|
|
89
|
+
if (!hasQD)
|
|
48
90
|
continue;
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
if (
|
|
91
|
+
const exprText = pa.getExpression().getText().trim();
|
|
92
|
+
const key = `?.:${exprText}`;
|
|
93
|
+
if (seen.has(key))
|
|
52
94
|
continue;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
95
|
+
seen.add(key);
|
|
96
|
+
branches.push({
|
|
97
|
+
condition: `${exprText}?.`,
|
|
98
|
+
trueLabel: `handles when ${simplifyCondition(exprText)} is defined`,
|
|
99
|
+
falseLabel: `handles when ${simplifyCondition(exprText)} is null/undefined (optional chain short-circuits)`,
|
|
100
|
+
kind: "optionalchain",
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// ── Switch statements ─────────────────────────────────────────────────
|
|
104
|
+
const switchStatements = fnNode.getDescendantsOfKind(ts_morph_1.SyntaxKind.SwitchStatement);
|
|
105
|
+
for (const sw of switchStatements) {
|
|
106
|
+
const exprText = sw.getExpression().getText().trim();
|
|
107
|
+
const clauses = sw.getCaseBlock().getClauses();
|
|
108
|
+
const labels = [];
|
|
109
|
+
for (const clause of clauses) {
|
|
110
|
+
if (clause.getKind() === ts_morph_1.SyntaxKind.CaseClause) {
|
|
111
|
+
labels.push(clause.getExpression().getText().trim());
|
|
112
|
+
}
|
|
57
113
|
}
|
|
58
|
-
const
|
|
59
|
-
if (seen.has(
|
|
114
|
+
const key = `switch:${exprText}`;
|
|
115
|
+
if (seen.has(key))
|
|
60
116
|
continue;
|
|
61
|
-
seen.add(
|
|
117
|
+
seen.add(key);
|
|
118
|
+
const caseList = labels.slice(0, 3).join(", ") + (labels.length > 3 ? ", ..." : "");
|
|
62
119
|
branches.push({
|
|
63
|
-
condition:
|
|
64
|
-
trueLabel: `handles case
|
|
65
|
-
falseLabel: `handles case
|
|
66
|
-
kind: "
|
|
120
|
+
condition: `switch (${exprText})`,
|
|
121
|
+
trueLabel: `handles case ${labels[0] ?? "matching"}`,
|
|
122
|
+
falseLabel: `handles default/unmatched case${caseList ? ` (cases: ${caseList})` : ""}`,
|
|
123
|
+
kind: "switch",
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// ── Try/catch blocks ──────────────────────────────────────────────────
|
|
127
|
+
const tryBlocks = fnNode.getDescendantsOfKind(ts_morph_1.SyntaxKind.TryStatement);
|
|
128
|
+
for (const tryStmt of tryBlocks) {
|
|
129
|
+
const key = `try:${tryStmt.getStartLineNumber()}`;
|
|
130
|
+
if (seen.has(key))
|
|
131
|
+
continue;
|
|
132
|
+
seen.add(key);
|
|
133
|
+
branches.push({
|
|
134
|
+
condition: `try/catch at line ${tryStmt.getStartLineNumber()}`,
|
|
135
|
+
trueLabel: `succeeds without throwing`,
|
|
136
|
+
falseLabel: `handles error thrown inside try block`,
|
|
137
|
+
kind: "trycatch",
|
|
67
138
|
});
|
|
68
139
|
}
|
|
69
140
|
return branches;
|
|
@@ -134,10 +205,12 @@ function simplifyCondition(cond) {
|
|
|
134
205
|
return `${cond} is truthy`;
|
|
135
206
|
}
|
|
136
207
|
// "a > b" → keep as is
|
|
137
|
-
if (cond.length <
|
|
208
|
+
if (cond.length < 60)
|
|
138
209
|
return cond;
|
|
139
|
-
// Truncate long conditions
|
|
140
|
-
|
|
210
|
+
// Truncate long conditions at a word boundary to preserve semantic meaning
|
|
211
|
+
const truncated = cond.substring(0, 57);
|
|
212
|
+
const lastSpace = truncated.lastIndexOf(" ");
|
|
213
|
+
return (lastSpace > 20 ? truncated.substring(0, lastSpace) : truncated) + "...";
|
|
141
214
|
}
|
|
142
215
|
/**
|
|
143
216
|
* Create a negative version of a condition description.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branchAnalyzer.js","sourceRoot":"","sources":["../src/branchAnalyzer.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;;AAuBnE,
|
|
1
|
+
{"version":3,"file":"branchAnalyzer.js","sourceRoot":"","sources":["../src/branchAnalyzer.ts"],"names":[],"mappings":"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"}
|
package/dist/checker.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ interface FunctionCoverage {
|
|
|
4
4
|
name: string;
|
|
5
5
|
/** Whether a describe block for this name was found in the test file */
|
|
6
6
|
covered: boolean;
|
|
7
|
+
/** 1-based source line number (from FunctionMeta.lineNumber — for LCOV FN: records) */
|
|
8
|
+
lineNumber?: number;
|
|
7
9
|
}
|
|
8
10
|
export interface FileCoverage {
|
|
9
11
|
/** Absolute source file path */
|
|
@@ -21,6 +23,17 @@ export interface FileCoverage {
|
|
|
21
23
|
totalCount: number;
|
|
22
24
|
/** Number of functions whose @testgen-sig fingerprint no longer matches current source */
|
|
23
25
|
staleCount: number;
|
|
26
|
+
/** Total `expect(` calls found in the test file */
|
|
27
|
+
assertionCount: number;
|
|
28
|
+
/** Total `it(` / `test(` calls found in the test file */
|
|
29
|
+
testCaseCount: number;
|
|
30
|
+
/**
|
|
31
|
+
* Heuristic quality score (0–100):
|
|
32
|
+
* - 0 when no test file exists
|
|
33
|
+
* - Based on assertion density (assertions per test case) and test case count
|
|
34
|
+
* - A = 80+, B = 60–79, C = 40–59, D = <40
|
|
35
|
+
*/
|
|
36
|
+
qualityScore: number;
|
|
24
37
|
}
|
|
25
38
|
export interface CheckResult {
|
|
26
39
|
fileCoverages: FileCoverage[];
|
package/dist/checker.js
CHANGED
|
@@ -104,17 +104,39 @@ function computeCoverage(scanRoot, projectRoot, config) {
|
|
|
104
104
|
const absSrcRoot = path.resolve(projectRoot, config.srcDir);
|
|
105
105
|
for (const srcPath of sourceFiles) {
|
|
106
106
|
const rawFunctions = safeAnalyze(srcPath, projectRoot);
|
|
107
|
-
|
|
107
|
+
// R-2: track empty files (types-only) — don't silently skip them
|
|
108
|
+
if (rawFunctions.length === 0) {
|
|
109
|
+
fileCoverages.push({
|
|
110
|
+
srcPath,
|
|
111
|
+
relPath: path.relative(projectRoot, srcPath).replace(/\\/g, "/"),
|
|
112
|
+
testPath: (0, utils_1.mirrorPath)(srcPath, absSrcRoot, path.join(projectRoot, config.testDir), ".test.ts"),
|
|
113
|
+
testFileExists: false,
|
|
114
|
+
functions: [],
|
|
115
|
+
coveredCount: 0,
|
|
116
|
+
totalCount: 0,
|
|
117
|
+
staleCount: 0,
|
|
118
|
+
assertionCount: 0,
|
|
119
|
+
testCaseCount: 0,
|
|
120
|
+
qualityScore: 0,
|
|
121
|
+
});
|
|
108
122
|
continue;
|
|
123
|
+
}
|
|
109
124
|
const testPath = (0, utils_1.mirrorPath)(srcPath, absSrcRoot, path.join(projectRoot, config.testDir), ".test.ts");
|
|
110
125
|
const testFileExists = fs.existsSync(testPath);
|
|
111
126
|
const testContent = readTestContent(testPath);
|
|
112
127
|
const functionCoverages = rawFunctions.map((fn) => ({
|
|
113
128
|
name: fn.name,
|
|
114
129
|
covered: isCovered(fn.name, testContent),
|
|
130
|
+
lineNumber: fn.lineNumber,
|
|
115
131
|
}));
|
|
116
132
|
const fileCoveredCount = functionCoverages.filter((f) => f.covered).length;
|
|
117
133
|
const fileStaleCount = detectStaleCount(testContent, rawFunctions);
|
|
134
|
+
// H-2: strip comments before counting to avoid false positives
|
|
135
|
+
const strippedContent = stripComments(testContent);
|
|
136
|
+
const assertionCount = countOccurrences(strippedContent, "expect(");
|
|
137
|
+
// H-2: exclude it.skip / it.todo / xit / test.skip / test.todo from active test count
|
|
138
|
+
const testCaseCount = countActiveTestCases(strippedContent);
|
|
139
|
+
const qualityScore = computeQualityScore(assertionCount, testCaseCount, testFileExists);
|
|
118
140
|
totalFunctions += functionCoverages.length;
|
|
119
141
|
coveredFunctions += fileCoveredCount;
|
|
120
142
|
totalStale += fileStaleCount;
|
|
@@ -127,8 +149,13 @@ function computeCoverage(scanRoot, projectRoot, config) {
|
|
|
127
149
|
coveredCount: fileCoveredCount,
|
|
128
150
|
totalCount: functionCoverages.length,
|
|
129
151
|
staleCount: fileStaleCount,
|
|
152
|
+
assertionCount,
|
|
153
|
+
testCaseCount,
|
|
154
|
+
qualityScore,
|
|
130
155
|
});
|
|
131
156
|
}
|
|
157
|
+
// L-1: sort by relPath for reproducible output across Windows/Linux
|
|
158
|
+
fileCoverages.sort((a, b) => a.relPath.localeCompare(b.relPath));
|
|
132
159
|
const coveragePercent = totalFunctions === 0 ? 100 : Math.round((coveredFunctions / totalFunctions) * 100);
|
|
133
160
|
return {
|
|
134
161
|
fileCoverages,
|
|
@@ -337,6 +364,54 @@ function isCovered(fnName, testContent) {
|
|
|
337
364
|
const pattern = new RegExp(`describe\\s*\\(\\s*['"\`]${escaped}['"\`]`);
|
|
338
365
|
return pattern.test(testContent);
|
|
339
366
|
}
|
|
367
|
+
/**
|
|
368
|
+
* Strip single-line (//) and multi-line (/* *\/) comments from source text.
|
|
369
|
+
* This prevents expect( or it( inside comments from inflating quality scores (H-2).
|
|
370
|
+
*/
|
|
371
|
+
function stripComments(src) {
|
|
372
|
+
// Remove block comments first, then line comments
|
|
373
|
+
return src
|
|
374
|
+
.replace(/\/\*[\s\S]*?\*\//g, " ")
|
|
375
|
+
.replace(/\/\/[^\n]*/g, " ");
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Count active (non-skipped) test cases: it(, test( — excluding
|
|
379
|
+
* it.skip(, it.todo(, xit(, xtest(, test.skip(, test.todo( (H-2).
|
|
380
|
+
*/
|
|
381
|
+
function countActiveTestCases(src) {
|
|
382
|
+
// Match standalone it( and test( but not the .skip/.todo variants
|
|
383
|
+
const itMatches = (src.match(/(?<![.\w])it\s*\(/g) ?? []).length;
|
|
384
|
+
const testMatches = (src.match(/(?<![.\w])test\s*\(/g) ?? []).length;
|
|
385
|
+
const skipMatches = (src.match(/(?:it|test)\.(?:skip|todo)\s*\(/g) ?? []).length;
|
|
386
|
+
const xMatches = (src.match(/(?:xit|xtest)\s*\(/g) ?? []).length;
|
|
387
|
+
return Math.max(0, itMatches + testMatches - skipMatches - xMatches);
|
|
388
|
+
}
|
|
389
|
+
/** Count non-overlapping occurrences of `needle` in `haystack`. */
|
|
390
|
+
function countOccurrences(haystack, needle) {
|
|
391
|
+
if (!haystack || !needle)
|
|
392
|
+
return 0;
|
|
393
|
+
let count = 0;
|
|
394
|
+
let idx = 0;
|
|
395
|
+
while ((idx = haystack.indexOf(needle, idx)) !== -1) {
|
|
396
|
+
count++;
|
|
397
|
+
idx += needle.length;
|
|
398
|
+
}
|
|
399
|
+
return count;
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Heuristic quality score (0–100).
|
|
403
|
+
* - 0 when no test file exists
|
|
404
|
+
* - Rewards assertion density and number of test cases
|
|
405
|
+
* - A = 80+, B = 60–79, C = 40–59, D = <40
|
|
406
|
+
*/
|
|
407
|
+
function computeQualityScore(assertionCount, testCaseCount, testFileExists) {
|
|
408
|
+
if (!testFileExists || testCaseCount === 0)
|
|
409
|
+
return 0;
|
|
410
|
+
const density = assertionCount / testCaseCount; // avg assertions per test
|
|
411
|
+
const densityScore = Math.min(50, density * 25); // up to 50 pts for ≥2 asserts/test
|
|
412
|
+
const caseScore = Math.min(50, testCaseCount * 5); // up to 50 pts for ≥10 test cases
|
|
413
|
+
return Math.round(densityScore + caseScore);
|
|
414
|
+
}
|
|
340
415
|
/** Safely analyse a file, returning [] on any error. */
|
|
341
416
|
function safeAnalyze(filePath, projectRoot) {
|
|
342
417
|
try {
|