assertloom 0.0.0-stage → 0.1.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.
Files changed (126) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +346 -2
  3. package/dist/ai/index.d.ts +5 -0
  4. package/dist/ai/index.js +14 -0
  5. package/dist/ai/index.js.map +1 -0
  6. package/dist/ai/openai.d.ts +9 -0
  7. package/dist/ai/openai.js +57 -0
  8. package/dist/ai/openai.js.map +1 -0
  9. package/dist/ai/pricing.d.ts +27 -0
  10. package/dist/ai/pricing.js +76 -0
  11. package/dist/ai/pricing.js.map +1 -0
  12. package/dist/ai/prompts.d.ts +27 -0
  13. package/dist/ai/prompts.js +89 -0
  14. package/dist/ai/prompts.js.map +1 -0
  15. package/dist/ai/provider.d.ts +26 -0
  16. package/dist/ai/provider.js +4 -0
  17. package/dist/ai/provider.js.map +1 -0
  18. package/dist/ai/redact.d.ts +5 -0
  19. package/dist/ai/redact.js +31 -0
  20. package/dist/ai/redact.js.map +1 -0
  21. package/dist/analyzer/dependencies.d.ts +16 -0
  22. package/dist/analyzer/dependencies.js +168 -0
  23. package/dist/analyzer/dependencies.js.map +1 -0
  24. package/dist/analyzer/format.d.ts +3 -0
  25. package/dist/analyzer/format.js +14 -0
  26. package/dist/analyzer/format.js.map +1 -0
  27. package/dist/analyzer/functions.d.ts +4 -0
  28. package/dist/analyzer/functions.js +274 -0
  29. package/dist/analyzer/functions.js.map +1 -0
  30. package/dist/analyzer/index.d.ts +5 -0
  31. package/dist/analyzer/index.js +29 -0
  32. package/dist/analyzer/index.js.map +1 -0
  33. package/dist/analyzer/parser.d.ts +11 -0
  34. package/dist/analyzer/parser.js +38 -0
  35. package/dist/analyzer/parser.js.map +1 -0
  36. package/dist/analyzer/usage.d.ts +16 -0
  37. package/dist/analyzer/usage.js +159 -0
  38. package/dist/analyzer/usage.js.map +1 -0
  39. package/dist/cli/commands/analyze.d.ts +2 -0
  40. package/dist/cli/commands/analyze.js +49 -0
  41. package/dist/cli/commands/analyze.js.map +1 -0
  42. package/dist/cli/commands/generate.d.ts +3 -0
  43. package/dist/cli/commands/generate.js +200 -0
  44. package/dist/cli/commands/generate.js.map +1 -0
  45. package/dist/cli/commands/run.d.ts +4 -0
  46. package/dist/cli/commands/run.js +53 -0
  47. package/dist/cli/commands/run.js.map +1 -0
  48. package/dist/cli/index.d.ts +2 -0
  49. package/dist/cli/index.js +16 -0
  50. package/dist/cli/index.js.map +1 -0
  51. package/dist/cli/program.d.ts +2 -0
  52. package/dist/cli/program.js +18 -0
  53. package/dist/cli/program.js.map +1 -0
  54. package/dist/cli/report.d.ts +3 -0
  55. package/dist/cli/report.js +36 -0
  56. package/dist/cli/report.js.map +1 -0
  57. package/dist/cli/validateFile.d.ts +5 -0
  58. package/dist/cli/validateFile.js +43 -0
  59. package/dist/cli/validateFile.js.map +1 -0
  60. package/dist/errors.d.ts +4 -0
  61. package/dist/errors.js +8 -0
  62. package/dist/errors.js.map +1 -0
  63. package/dist/generator/diff.d.ts +5 -0
  64. package/dist/generator/diff.js +56 -0
  65. package/dist/generator/diff.js.map +1 -0
  66. package/dist/generator/importPlan.d.ts +15 -0
  67. package/dist/generator/importPlan.js +62 -0
  68. package/dist/generator/importPlan.js.map +1 -0
  69. package/dist/generator/index.d.ts +5 -0
  70. package/dist/generator/index.js +6 -0
  71. package/dist/generator/index.js.map +1 -0
  72. package/dist/generator/mocks.d.ts +48 -0
  73. package/dist/generator/mocks.js +356 -0
  74. package/dist/generator/mocks.js.map +1 -0
  75. package/dist/generator/schema.d.ts +40 -0
  76. package/dist/generator/schema.js +15 -0
  77. package/dist/generator/schema.js.map +1 -0
  78. package/dist/generator/testGenerator.d.ts +33 -0
  79. package/dist/generator/testGenerator.js +80 -0
  80. package/dist/generator/testGenerator.js.map +1 -0
  81. package/dist/generator/testWriter.d.ts +22 -0
  82. package/dist/generator/testWriter.js +93 -0
  83. package/dist/generator/testWriter.js.map +1 -0
  84. package/dist/generator/validate.d.ts +31 -0
  85. package/dist/generator/validate.js +180 -0
  86. package/dist/generator/validate.js.map +1 -0
  87. package/dist/repair/classifyFailure.d.ts +11 -0
  88. package/dist/repair/classifyFailure.js +26 -0
  89. package/dist/repair/classifyFailure.js.map +1 -0
  90. package/dist/repair/index.d.ts +2 -0
  91. package/dist/repair/index.js +3 -0
  92. package/dist/repair/index.js.map +1 -0
  93. package/dist/repair/repairLoop.d.ts +74 -0
  94. package/dist/repair/repairLoop.js +219 -0
  95. package/dist/repair/repairLoop.js.map +1 -0
  96. package/dist/repair/schema.d.ts +17 -0
  97. package/dist/repair/schema.js +14 -0
  98. package/dist/repair/schema.js.map +1 -0
  99. package/dist/runner/coverage.d.ts +5 -0
  100. package/dist/runner/coverage.js +42 -0
  101. package/dist/runner/coverage.js.map +1 -0
  102. package/dist/runner/index.d.ts +4 -0
  103. package/dist/runner/index.js +4 -0
  104. package/dist/runner/index.js.map +1 -0
  105. package/dist/runner/jestConfig.d.ts +11 -0
  106. package/dist/runner/jestConfig.js +103 -0
  107. package/dist/runner/jestConfig.js.map +1 -0
  108. package/dist/runner/jestRunner.d.ts +14 -0
  109. package/dist/runner/jestRunner.js +140 -0
  110. package/dist/runner/jestRunner.js.map +1 -0
  111. package/dist/runner/networkGuard.d.ts +4 -0
  112. package/dist/runner/networkGuard.js +55 -0
  113. package/dist/runner/networkGuard.js.map +1 -0
  114. package/dist/runner/project.d.ts +30 -0
  115. package/dist/runner/project.js +86 -0
  116. package/dist/runner/project.js.map +1 -0
  117. package/dist/runner/results.d.ts +32 -0
  118. package/dist/runner/results.js +58 -0
  119. package/dist/runner/results.js.map +1 -0
  120. package/dist/runner/types.d.ts +39 -0
  121. package/dist/runner/types.js +2 -0
  122. package/dist/runner/types.js.map +1 -0
  123. package/dist/types/index.d.ts +95 -0
  124. package/dist/types/index.js +2 -0
  125. package/dist/types/index.js.map +1 -0
  126. package/package.json +66 -4
@@ -0,0 +1,62 @@
1
+ import path from "node:path";
2
+ const RESERVED = new Set(("break case catch class const continue debugger default delete do else enum export extends false finally for function if import in " +
3
+ "instanceof new null return super switch this throw true try typeof var void while with yield let static implements interface " +
4
+ "package private protected public await arguments eval undefined NaN Infinity").split(" "));
5
+ const isIdentifierName = (name) => /^[A-Za-z_$][\w$]*$/.test(name);
6
+ function camelCase(text) {
7
+ const words = text.split(/[^A-Za-z0-9]+/).filter(Boolean);
8
+ const joined = words.map((w, i) => (i === 0 ? w[0].toLowerCase() : w[0].toUpperCase()) + w.slice(1)).join("");
9
+ return /^[A-Za-z_$]/.test(joined) ? joined : `_${joined}`;
10
+ }
11
+ /** A local binding name for `name` that is a valid, unused, non-reserved identifier. */
12
+ function localName(name, used) {
13
+ let base = isIdentifierName(name) ? name : camelCase(name);
14
+ if (RESERVED.has(base))
15
+ base = `_${base}`;
16
+ let binding = base;
17
+ for (let n = 2; used.has(binding); n++)
18
+ binding = `${base}${n}`;
19
+ used.add(binding);
20
+ return binding;
21
+ }
22
+ const exportKey = (name) => (isIdentifierName(name) ? name : JSON.stringify(name));
23
+ /** Module specifier for importing `sourcePath` from a test file at `testPath`. */
24
+ export function importSpecifier(testPath, sourcePath) {
25
+ let relative = path.relative(path.dirname(testPath), sourcePath).replaceAll("\\", "/");
26
+ relative = relative.replace(/\.(ts|tsx|js|jsx)$/, "");
27
+ return relative.startsWith(".") ? relative : `./${relative}`;
28
+ }
29
+ export function planImports(analysis, functions, sourcePath, testPath) {
30
+ const bindings = [];
31
+ const used = new Set();
32
+ for (const fn of functions) {
33
+ const named = fn.exportedAs.find((name) => name !== "default");
34
+ if (named)
35
+ bindings.push({ binding: localName(named, used), exportName: named, fn });
36
+ }
37
+ for (const fn of functions) {
38
+ if (fn.exportedAs.some((name) => name !== "default") || !fn.exportedAs.includes("default"))
39
+ continue;
40
+ const base = fn.name !== "default" ? fn.name : camelCase(path.basename(sourcePath).replace(/\.[^.]+$/, ""));
41
+ bindings.push({ binding: localName(used.has(base) ? `${base}Default` : base, used), exportName: "default", fn });
42
+ }
43
+ const specifier = JSON.stringify(importSpecifier(testPath, sourcePath));
44
+ const defaultBinding = bindings.find((b) => b.exportName === "default")?.binding;
45
+ const named = bindings.filter((b) => b.exportName !== "default");
46
+ const statements = [];
47
+ if (analysis.moduleSystem === "commonjs") {
48
+ const properties = named.map((b) => (b.binding === b.exportName ? b.binding : `${exportKey(b.exportName)}: ${b.binding}`));
49
+ if (defaultBinding)
50
+ statements.push(`const ${defaultBinding} = require(${specifier});`);
51
+ if (properties.length)
52
+ statements.push(`const { ${properties.join(", ")} } = require(${specifier});`);
53
+ }
54
+ else {
55
+ const specifiers = named.map((b) => (b.binding === b.exportName ? b.binding : `${exportKey(b.exportName)} as ${b.binding}`));
56
+ const clauses = [defaultBinding, specifiers.length ? `{ ${specifiers.join(", ")} }` : undefined].filter(Boolean);
57
+ if (clauses.length)
58
+ statements.push(`import ${clauses.join(", ")} from ${specifier};`);
59
+ }
60
+ return { statements, bindings };
61
+ }
62
+ //# sourceMappingURL=importPlan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"importPlan.js","sourceRoot":"","sources":["../../src/generator/importPlan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { generateTests, GenerationError, type GenerationResult } from "./testGenerator.js";
2
+ export { planMocks, PURE_BUILTINS, PURE_PACKAGES, type MockedModule, type MockPlan, type RealModule } from "./mocks.js";
3
+ export { previewPathFor, renderTestFile, testPathFor, writeTestFile, TestFileExistsError } from "./testWriter.js";
4
+ export { unifiedDiff } from "./diff.js";
5
+ export { checkBody, type AcceptedCase, type ValidatedSuite } from "./validate.js";
@@ -0,0 +1,6 @@
1
+ export { generateTests, GenerationError } from "./testGenerator.js";
2
+ export { planMocks, PURE_BUILTINS, PURE_PACKAGES } from "./mocks.js";
3
+ export { previewPathFor, renderTestFile, testPathFor, writeTestFile, TestFileExistsError } from "./testWriter.js";
4
+ export { unifiedDiff } from "./diff.js";
5
+ export { checkBody } from "./validate.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAyB,MAAM,oBAAoB,CAAC;AAC3F,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAqD,MAAM,YAAY,CAAC;AACxH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAClH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,SAAS,EAA0C,MAAM,eAAe,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { type FileAnalysis, type ImportCategory, type SupportedExtension } from "../types/index.js";
2
+ /** Built-ins that are deterministic and side-effect free, so they stay real. */
3
+ export declare const PURE_BUILTINS: Set<string>;
4
+ /** Utility packages without I/O. Mocking them would break the code under test, so they stay real. */
5
+ export declare const PURE_PACKAGES: Set<string>;
6
+ export interface MockedModule {
7
+ /** Specifier as written in the source. */
8
+ source: string;
9
+ /** Specifier used in the test file. */
10
+ specifier: string;
11
+ category: ImportCategory;
12
+ /** The module is not installed or not found, so Jest must not try to resolve it. */
13
+ virtual: boolean;
14
+ reason: string;
15
+ }
16
+ export interface RealModule {
17
+ source: string;
18
+ reason: string;
19
+ }
20
+ export interface MockPlan {
21
+ mocked: MockedModule[];
22
+ real: RealModule[];
23
+ globals: string[];
24
+ /** jest.mock() calls and imports of the mocked modules; they go before the source import. */
25
+ imports: string[];
26
+ /** Shared mock objects, global mocks, and reset hooks; they go after all imports. */
27
+ setup: string[];
28
+ /** Description of the mocks for the model. */
29
+ summary: string;
30
+ }
31
+ export interface MockOptions {
32
+ analysis: FileAnalysis;
33
+ sourcePath: string;
34
+ testPath: string;
35
+ extension: SupportedExtension;
36
+ /** Names already used in the test file (the source function bindings). */
37
+ reserved: Iterable<string>;
38
+ /** Modules to mock even if Assertloom would keep them real. Matched by specifier or package name. */
39
+ mock?: string[];
40
+ /** Modules to keep real even if Assertloom would mock them. */
41
+ keepReal?: string[];
42
+ }
43
+ export declare function resolveLocal(fromFile: string, specifier: string): Promise<string | undefined>;
44
+ /**
45
+ * Decides which imports to mock and writes the mocks. Assertloom writes every jest.mock() factory
46
+ * itself from how the source uses each import; the model only configures return values in tests.
47
+ */
48
+ export declare function planMocks(options: MockOptions): Promise<MockPlan>;
@@ -0,0 +1,356 @@
1
+ import { readFile, stat } from "node:fs/promises";
2
+ import { createRequire } from "node:module";
3
+ import path from "node:path";
4
+ import { classifySource, scanImports } from "../analyzer/dependencies.js";
5
+ import { parseSource } from "../analyzer/parser.js";
6
+ import { collectImportUsage, emptyShape } from "../analyzer/usage.js";
7
+ import { SUPPORTED_EXTENSIONS } from "../types/index.js";
8
+ /** Built-ins that are deterministic and side-effect free, so they stay real. */
9
+ export const PURE_BUILTINS = new Set(["assert", "buffer", "path", "path/posix", "path/win32", "querystring", "string_decoder", "url", "util"]);
10
+ /** Utility packages without I/O. Mocking them would break the code under test, so they stay real. */
11
+ export const PURE_PACKAGES = new Set([
12
+ "@babel/runtime", "big.js", "bignumber.js", "change-case", "classnames", "clsx", "date-fns", "dayjs", "decimal.js",
13
+ "deepmerge", "fast-deep-equal", "immer", "joi", "lodash", "lodash-es", "ms", "qs", "ramda", "semver", "tslib",
14
+ "validator", "yup", "zod",
15
+ ]);
16
+ const MAX_LOCAL_DEPTH = 5;
17
+ const TYPESCRIPT_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts"];
18
+ async function isFile(file) {
19
+ try {
20
+ return (await stat(file)).isFile();
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ }
26
+ export async function resolveLocal(fromFile, specifier) {
27
+ if (specifier.startsWith("#"))
28
+ return undefined;
29
+ const base = path.resolve(path.dirname(fromFile), specifier);
30
+ const candidates = [base];
31
+ const jsExtension = /\.[cm]?jsx?$/.exec(base);
32
+ if (jsExtension)
33
+ candidates.push(...TYPESCRIPT_EXTENSIONS.map((ext) => base.slice(0, -jsExtension[0].length) + ext));
34
+ candidates.push(...SUPPORTED_EXTENSIONS.map((ext) => base + ext), ...SUPPORTED_EXTENSIONS.map((ext) => path.join(base, `index${ext}`)));
35
+ for (const candidate of candidates)
36
+ if (await isFile(candidate))
37
+ return candidate;
38
+ return undefined;
39
+ }
40
+ function isInstalled(fromFile, specifier) {
41
+ try {
42
+ createRequire(fromFile).resolve(specifier);
43
+ return true;
44
+ }
45
+ catch {
46
+ return false;
47
+ }
48
+ }
49
+ /** Why a local file has side effects (its first impure dependency), or undefined if it has none. */
50
+ async function localImpurity(file, visited, depth) {
51
+ if (visited.has(file))
52
+ return undefined;
53
+ visited.add(file);
54
+ const extension = path.extname(file);
55
+ if (!SUPPORTED_EXTENSIONS.includes(extension))
56
+ return undefined;
57
+ if (depth > MAX_LOCAL_DEPTH)
58
+ return "deeply nested local modules";
59
+ let ast;
60
+ try {
61
+ ast = parseSource(await readFile(file, "utf8"), extension);
62
+ }
63
+ catch {
64
+ return `${path.basename(file)}, which could not be parsed`;
65
+ }
66
+ const { globals } = collectImportUsage(ast);
67
+ if (globals.length)
68
+ return `global ${globals[0]}`;
69
+ for (const entry of scanImports(ast).imports) {
70
+ if (entry.typeOnly)
71
+ continue;
72
+ const decision = await decide(entry.source, entry.category, entry.packageName, file, visited, depth + 1);
73
+ if (decision.mock)
74
+ return entry.category === "local" ? `${entry.source} (${decision.reason})` : entry.source;
75
+ }
76
+ return undefined;
77
+ }
78
+ async function decide(source, category, packageName, fromFile, visited, depth) {
79
+ if (category === "builtin") {
80
+ return PURE_BUILTINS.has(source.replace(/^node:/, ""))
81
+ ? { mock: false, virtual: false, reason: "pure Node built-in" }
82
+ : { mock: true, virtual: false, reason: "Node built-in with side effects" };
83
+ }
84
+ if (category === "external") {
85
+ if (packageName && PURE_PACKAGES.has(packageName))
86
+ return { mock: false, virtual: false, reason: "utility library without I/O" };
87
+ const installed = isInstalled(fromFile, source);
88
+ return { mock: true, virtual: !installed, reason: installed ? "external package" : "external package, not installed" };
89
+ }
90
+ const file = await resolveLocal(fromFile, source);
91
+ if (!file)
92
+ return { mock: true, virtual: true, reason: "local module not found" };
93
+ const impurity = await localImpurity(file, visited, depth);
94
+ return impurity
95
+ ? { mock: true, virtual: false, reason: `depends on ${impurity}` }
96
+ : { mock: false, virtual: false, reason: "local module without side effects" };
97
+ }
98
+ function matches(list, source, packageName) {
99
+ return !!list?.some((entry) => entry === source || entry === packageName || entry.replace(/^node:/, "") === source.replace(/^node:/, ""));
100
+ }
101
+ function specifierFromTest(source, sourcePath, testPath) {
102
+ if (!source.startsWith("."))
103
+ return source;
104
+ const relative = path.relative(path.dirname(testPath), path.resolve(path.dirname(sourcePath), source)).replaceAll("\\", "/");
105
+ return relative.startsWith(".") ? relative : `./${relative}`;
106
+ }
107
+ function mergeShapes(a, b) {
108
+ const merged = a
109
+ ? { ...a, members: { ...a.members }, resultNames: [...a.resultNames] }
110
+ : { ...emptyShape(), members: {}, resultNames: [] };
111
+ merged.called ||= b.called;
112
+ merged.constructed ||= b.constructed;
113
+ merged.instanceOf ||= b.instanceOf;
114
+ merged.createdAtLoad ||= b.createdAtLoad;
115
+ for (const name of b.resultNames)
116
+ if (!merged.resultNames.includes(name))
117
+ merged.resultNames.push(name);
118
+ for (const [key, value] of Object.entries(b.members))
119
+ merged.members[key] = mergeShapes(merged.members[key], value);
120
+ if (b.result)
121
+ merged.result = mergeShapes(merged.result, b.result);
122
+ return merged;
123
+ }
124
+ /**
125
+ * Constructors, and calls made while the module loads (`const client = createClient()`), return one
126
+ * shared mock object, because tests cannot configure them before they run. Other calls are plain
127
+ * jest.fn() mocks whose return values tests set themselves.
128
+ */
129
+ function sharesInstance(shape) {
130
+ return !!shape.result && (shape.constructed || shape.createdAtLoad);
131
+ }
132
+ const isCallable = (shape) => shape.called || shape.constructed || shape.instanceOf;
133
+ function propertyKey(name) {
134
+ return /^[A-Za-z_$][\w$]*$/.test(name) ? name : JSON.stringify(name);
135
+ }
136
+ class FactoryWriter {
137
+ locals = [];
138
+ count = 0;
139
+ members(shape) {
140
+ return Object.entries(shape.members).map(([key, value]) => `${propertyKey(key)}: ${this.value(value)}`);
141
+ }
142
+ /** A member that is only read (never called) is still a jest.fn(), the safest stand-in for an unknown value. */
143
+ value(shape) {
144
+ const members = this.members(shape);
145
+ const withMembers = (base) => (members.length ? `Object.assign(${base}, { ${members.join(", ")} })` : base);
146
+ if (sharesInstance(shape)) {
147
+ const name = `instance${++this.count}`;
148
+ this.locals.push(`const ${name} = ${this.object(shape.result)};`);
149
+ return withMembers(`function () { return ${name}; }`);
150
+ }
151
+ if (shape.instanceOf && !shape.called && !shape.constructed)
152
+ return withMembers("class {}");
153
+ if (shape.called || shape.constructed || members.length === 0)
154
+ return withMembers("jest.fn()");
155
+ return `{ ${members.join(", ")} }`;
156
+ }
157
+ object(shape) {
158
+ const members = this.members(shape);
159
+ return members.length ? `{ ${members.join(", ")} }` : "{}";
160
+ }
161
+ }
162
+ function modelModule(usages) {
163
+ let defaultShape;
164
+ let moduleShape = emptyShape();
165
+ for (const usage of usages) {
166
+ if (usage.imported === "default" && usage.style === "esm")
167
+ defaultShape = mergeShapes(defaultShape, usage.shape);
168
+ else if (usage.imported === "*")
169
+ moduleShape = mergeShapes(moduleShape, usage.shape);
170
+ else
171
+ moduleShape.members[usage.imported] = mergeShapes(moduleShape.members[usage.imported], usage.shape);
172
+ }
173
+ return { defaultShape, moduleShape, hasEsm: usages.some((u) => u.style === "esm"), callableRoot: !defaultShape && isCallable(moduleShape) };
174
+ }
175
+ function factoryFor(model) {
176
+ const writer = new FactoryWriter();
177
+ let value;
178
+ if (model.callableRoot) {
179
+ value = writer.value(model.moduleShape);
180
+ }
181
+ else {
182
+ const members = [
183
+ ...(model.hasEsm ? ["__esModule: true"] : []),
184
+ ...(model.defaultShape ? [`default: ${writer.value(model.defaultShape)}`] : []),
185
+ ...writer.members(model.moduleShape),
186
+ ];
187
+ value = members.length ? `{ ${members.join(", ")} }` : "{}";
188
+ }
189
+ if (writer.locals.length === 0)
190
+ return `() => (${value})`;
191
+ return `() => {\n ${writer.locals.join("\n ")}\n return ${value};\n}`;
192
+ }
193
+ function shapeFor(model, usage) {
194
+ if (usage.imported === "default" && usage.style === "esm")
195
+ return model.defaultShape;
196
+ if (usage.imported === "*")
197
+ return model.moduleShape;
198
+ return model.moduleShape.members[usage.imported];
199
+ }
200
+ class NameAllocator {
201
+ used;
202
+ constructor(reserved) {
203
+ this.used = new Set(reserved);
204
+ }
205
+ has(name) {
206
+ return this.used.has(name);
207
+ }
208
+ claim(preferred) {
209
+ let name = preferred;
210
+ for (let n = 2; this.used.has(name); n++)
211
+ name = `${preferred}Mock${n === 2 ? "" : n}`;
212
+ this.used.add(name);
213
+ return name;
214
+ }
215
+ }
216
+ function describeShape(shape, expr, names, out, isRoot) {
217
+ if (sharesInstance(shape)) {
218
+ const lastSegment = expr.split(/[.()\s]/).filter(Boolean).pop() ?? "mock";
219
+ const name = names.claim(shape.resultNames.find((n) => !names.has(n)) ?? `${lastSegment[0].toLowerCase()}${lastSegment.slice(1)}Instance`);
220
+ const init = shape.constructed ? `new ${expr}()` : `${expr}()`;
221
+ out.handles.push({ name, init });
222
+ out.lines.push(`\`${init}\` returns one shared mock object, available in tests as \`${name}\``);
223
+ describeShape(shape.result, name, names, out, false);
224
+ }
225
+ else if (shape.called || shape.constructed || (!isRoot && Object.keys(shape.members).length === 0)) {
226
+ out.fns.push(expr);
227
+ }
228
+ for (const [key, member] of Object.entries(shape.members)) {
229
+ const access = /^[A-Za-z_$][\w$]*$/.test(key) ? `${expr}.${key}` : `${expr}[${JSON.stringify(key)}]`;
230
+ describeShape(member, access, names, out, false);
231
+ }
232
+ }
233
+ function importStatement(usage, specifier, model, commonjs) {
234
+ const spec = JSON.stringify(specifier);
235
+ const local = usage.local;
236
+ if (commonjs) {
237
+ if (usage.imported === "default" && usage.style === "esm")
238
+ return `const ${local} = require(${spec}).default;`;
239
+ if (usage.imported === "*")
240
+ return `const ${local} = require(${spec});`;
241
+ return `const { ${usage.imported === local ? local : `${propertyKey(usage.imported)}: ${local}`} } = require(${spec});`;
242
+ }
243
+ if (usage.imported === "default" && usage.style === "esm")
244
+ return `import ${local} from ${spec};`;
245
+ if (usage.imported === "*")
246
+ return model.callableRoot ? `import ${local} from ${spec};` : `import * as ${local} from ${spec};`;
247
+ return `import { ${usage.imported === local ? local : `${JSON.stringify(usage.imported)} as ${local}`} } from ${spec};`;
248
+ }
249
+ /**
250
+ * Decides which imports to mock and writes the mocks. Assertloom writes every jest.mock() factory
251
+ * itself from how the source uses each import; the model only configures return values in tests.
252
+ */
253
+ export async function planMocks(options) {
254
+ const { analysis, sourcePath, testPath } = options;
255
+ const commonjs = analysis.moduleSystem === "commonjs";
256
+ const typescript = analysis.language === "typescript";
257
+ const names = new NameAllocator(options.reserved);
258
+ const mocked = [];
259
+ const real = [];
260
+ const seen = new Set();
261
+ for (const entry of analysis.imports) {
262
+ if (entry.typeOnly || (entry.kind !== "import" && entry.kind !== "require") || seen.has(entry.source))
263
+ continue;
264
+ seen.add(entry.source);
265
+ let decision;
266
+ if (matches(options.keepReal, entry.source, entry.packageName)) {
267
+ decision = { mock: false, virtual: false, reason: "kept real with --keep-real" };
268
+ }
269
+ else {
270
+ decision = await decide(entry.source, entry.category, entry.packageName, sourcePath, new Set([sourcePath]), 1);
271
+ if (!decision.mock && matches(options.mock, entry.source, entry.packageName)) {
272
+ const missing = entry.category === "external" ? !isInstalled(sourcePath, entry.source) : entry.category === "local" && !(await resolveLocal(sourcePath, entry.source));
273
+ decision = { mock: true, virtual: missing, reason: "mocked with --mock" };
274
+ }
275
+ }
276
+ if (decision.mock) {
277
+ mocked.push({
278
+ source: entry.source,
279
+ specifier: specifierFromTest(entry.source, sourcePath, testPath),
280
+ category: classifySource(entry.source).category,
281
+ virtual: decision.virtual,
282
+ reason: decision.reason,
283
+ });
284
+ }
285
+ else {
286
+ real.push({ source: entry.source, reason: decision.reason });
287
+ }
288
+ }
289
+ const mockCalls = [];
290
+ const imports = [];
291
+ const handles = [];
292
+ const summary = [];
293
+ for (const module of mocked) {
294
+ const usages = analysis.importUsage.filter((u) => u.source === module.source);
295
+ const model = modelModule(usages);
296
+ const virtual = module.virtual ? ", { virtual: true }" : "";
297
+ mockCalls.push(`jest.mock(${JSON.stringify(module.specifier)}, ${factoryFor(model)}${virtual});`);
298
+ const visible = usages.filter((u) => u.local && !names.has(u.local));
299
+ const locals = [...new Map(visible.map((u) => [u.local, u])).values()];
300
+ for (const usage of locals) {
301
+ names.claim(usage.local);
302
+ imports.push(importStatement(usage, module.specifier, model, commonjs));
303
+ }
304
+ const description = { handles: [], lines: [], fns: [] };
305
+ for (const usage of locals) {
306
+ const shape = shapeFor(model, usage);
307
+ if (shape)
308
+ describeShape(shape, usage.local, names, description, usage.imported === "*" || usage.imported === "default");
309
+ }
310
+ handles.push(...description.handles.map((h) => `const ${h.name} = ${h.init};`));
311
+ const detail = module.virtual ? `${module.reason}; virtual mock` : module.reason;
312
+ summary.push(`- ${JSON.stringify(module.source)} (${detail}). Imported in the test file as: ${locals.map((u) => `\`${u.local}\``).join(", ") || "(nothing)"}`);
313
+ for (const line of description.lines)
314
+ summary.push(` - ${line}`);
315
+ if (description.fns.length)
316
+ summary.push(` - jest.fn() mocks: ${[...new Set(description.fns)].map((f) => `\`${f}\``).join(", ")}`);
317
+ }
318
+ // Pure built-ins such as `path` are also imported into the test, so expected values can be built portably.
319
+ const helpers = [];
320
+ for (const module of real) {
321
+ if (classifySource(module.source).category !== "builtin")
322
+ continue;
323
+ const usages = analysis.importUsage.filter((u) => u.source === module.source && u.local && !names.has(u.local));
324
+ const model = modelModule(usages);
325
+ for (const usage of [...new Map(usages.map((u) => [u.local, u])).values()]) {
326
+ names.claim(usage.local);
327
+ imports.push(importStatement(usage, module.source, model, commonjs));
328
+ helpers.push(`\`${usage.local}\` (${module.source})`);
329
+ }
330
+ }
331
+ if (helpers.length)
332
+ summary.push(`- Not mocked, and also imported in the test file for building expected values: ${helpers.join(", ")}`);
333
+ const otherReal = real.filter((r) => classifySource(r.source).category !== "builtin");
334
+ if (otherReal.length)
335
+ summary.push(`- Not mocked (real code runs): ${otherReal.map((r) => JSON.stringify(r.source)).join(", ")}`);
336
+ const globals = analysis.globals;
337
+ const globalLines = [];
338
+ for (const name of globals) {
339
+ const original = names.claim(`original${name[0].toUpperCase()}${name.slice(1)}`);
340
+ globalLines.push(`const ${original} = globalThis.${name};`, `globalThis.${name} = jest.fn()${typescript ? ` as unknown as typeof ${name}` : ""};`, `afterAll(() => {\n globalThis.${name} = ${original};\n});`);
341
+ summary.push(`- global \`${name}\` is a jest.fn() mock for every test.`);
342
+ }
343
+ const setup = [handles.join("\n"), globalLines.join("\n")].filter(Boolean);
344
+ if (mocked.length > 0 || globals.length > 0) {
345
+ setup.push("beforeEach(() => {\n jest.resetAllMocks();\n});", "afterEach(() => {\n jest.restoreAllMocks();\n});");
346
+ }
347
+ return {
348
+ mocked,
349
+ real,
350
+ globals,
351
+ imports: [...mockCalls, ...(mockCalls.length ? [""] : []), ...imports],
352
+ setup,
353
+ summary: summary.join("\n"),
354
+ };
355
+ }
356
+ //# sourceMappingURL=mocks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mocks.js","sourceRoot":"","sources":["../../src/generator/mocks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { z } from "zod";
2
+ export declare const TEST_CATEGORIES: readonly ["normal", "edge", "error"];
3
+ export declare const GeneratedTestCaseSchema: z.ZodObject<{
4
+ name: z.ZodString;
5
+ category: z.ZodEnum<{
6
+ edge: "edge";
7
+ error: "error";
8
+ normal: "normal";
9
+ }>;
10
+ body: z.ZodString;
11
+ }, z.core.$strip>;
12
+ export declare const GeneratedSuiteSchema: z.ZodObject<{
13
+ functionName: z.ZodString;
14
+ cases: z.ZodArray<z.ZodObject<{
15
+ name: z.ZodString;
16
+ category: z.ZodEnum<{
17
+ edge: "edge";
18
+ error: "error";
19
+ normal: "normal";
20
+ }>;
21
+ body: z.ZodString;
22
+ }, z.core.$strip>>;
23
+ }, z.core.$strip>;
24
+ export declare const GenerationSchema: z.ZodObject<{
25
+ suites: z.ZodArray<z.ZodObject<{
26
+ functionName: z.ZodString;
27
+ cases: z.ZodArray<z.ZodObject<{
28
+ name: z.ZodString;
29
+ category: z.ZodEnum<{
30
+ edge: "edge";
31
+ error: "error";
32
+ normal: "normal";
33
+ }>;
34
+ body: z.ZodString;
35
+ }, z.core.$strip>>;
36
+ }, z.core.$strip>>;
37
+ }, z.core.$strip>;
38
+ export type GeneratedTestCase = z.infer<typeof GeneratedTestCaseSchema>;
39
+ export type GeneratedSuite = z.infer<typeof GeneratedSuiteSchema>;
40
+ export type Generation = z.infer<typeof GenerationSchema>;
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ export const TEST_CATEGORIES = ["normal", "edge", "error"];
3
+ export const GeneratedTestCaseSchema = z.object({
4
+ name: z.string().describe("Short description of the behavior under test, used as the `it` title"),
5
+ category: z.enum(TEST_CATEGORIES).describe("normal: typical input; edge: boundaries and unusual input; error: throws or rejects"),
6
+ body: z.string().describe("Statements inside the test callback, without the it() wrapper"),
7
+ });
8
+ export const GeneratedSuiteSchema = z.object({
9
+ functionName: z.string().describe("Binding name of the function under test, exactly as listed in the prompt"),
10
+ cases: z.array(GeneratedTestCaseSchema),
11
+ });
12
+ export const GenerationSchema = z.object({
13
+ suites: z.array(GeneratedSuiteSchema),
14
+ });
15
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/generator/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAEpE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sEAAsE,CAAC;IACjG,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,qFAAqF,CAAC;IACjI,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+DAA+D,CAAC;CAC3F,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0EAA0E,CAAC;IAC7G,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC;CACxC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC;CACtC,CAAC,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { type Budget } from "../ai/pricing.js";
2
+ import type { LLMProvider, TokenUsage } from "../ai/provider.js";
3
+ import { UserError } from "../errors.js";
4
+ import type { FileAnalysis, SourceFile } from "../types/index.js";
5
+ import { type MockPlan } from "./mocks.js";
6
+ import { type RejectedCase, type ValidatedSuite } from "./validate.js";
7
+ export declare class GenerationError extends UserError {
8
+ }
9
+ export interface GenerationResult {
10
+ analysis: FileAnalysis;
11
+ testPath: string;
12
+ content: string;
13
+ /** Mocks, imports, and setup that precede the describe blocks. */
14
+ preamble: string[];
15
+ mocks: MockPlan;
16
+ suites: ValidatedSuite[];
17
+ /** The source as sent to the model, with secrets redacted. */
18
+ promptSource: string;
19
+ rejected: RejectedCase[];
20
+ model: string;
21
+ usage: TokenUsage;
22
+ redactions: number;
23
+ }
24
+ export declare function generateTests(options: {
25
+ source: SourceFile;
26
+ provider: LLMProvider;
27
+ testPath?: string;
28
+ /** Modules to mock even if Assertloom would keep them real. */
29
+ mock?: string[];
30
+ /** Modules to keep real even if Assertloom would mock them. */
31
+ keepReal?: string[];
32
+ budget?: Budget;
33
+ }): Promise<GenerationResult>;