assertloom 0.0.0-stage → 0.2.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 (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +393 -2
  3. package/dist/ai/anthropic.d.ts +11 -0
  4. package/dist/ai/anthropic.js +68 -0
  5. package/dist/ai/anthropic.js.map +1 -0
  6. package/dist/ai/index.d.ts +12 -0
  7. package/dist/ai/index.js +23 -0
  8. package/dist/ai/index.js.map +1 -0
  9. package/dist/ai/openai.d.ts +9 -0
  10. package/dist/ai/openai.js +57 -0
  11. package/dist/ai/openai.js.map +1 -0
  12. package/dist/ai/openaiCompatible.d.ts +13 -0
  13. package/dist/ai/openaiCompatible.js +62 -0
  14. package/dist/ai/openaiCompatible.js.map +1 -0
  15. package/dist/ai/pricing.d.ts +38 -0
  16. package/dist/ai/pricing.js +105 -0
  17. package/dist/ai/pricing.js.map +1 -0
  18. package/dist/ai/prompts.d.ts +27 -0
  19. package/dist/ai/prompts.js +89 -0
  20. package/dist/ai/prompts.js.map +1 -0
  21. package/dist/ai/provider.d.ts +26 -0
  22. package/dist/ai/provider.js +4 -0
  23. package/dist/ai/provider.js.map +1 -0
  24. package/dist/ai/redact.d.ts +5 -0
  25. package/dist/ai/redact.js +31 -0
  26. package/dist/ai/redact.js.map +1 -0
  27. package/dist/analyzer/dependencies.d.ts +16 -0
  28. package/dist/analyzer/dependencies.js +168 -0
  29. package/dist/analyzer/dependencies.js.map +1 -0
  30. package/dist/analyzer/format.d.ts +3 -0
  31. package/dist/analyzer/format.js +14 -0
  32. package/dist/analyzer/format.js.map +1 -0
  33. package/dist/analyzer/functions.d.ts +4 -0
  34. package/dist/analyzer/functions.js +324 -0
  35. package/dist/analyzer/functions.js.map +1 -0
  36. package/dist/analyzer/index.d.ts +5 -0
  37. package/dist/analyzer/index.js +29 -0
  38. package/dist/analyzer/index.js.map +1 -0
  39. package/dist/analyzer/parser.d.ts +11 -0
  40. package/dist/analyzer/parser.js +38 -0
  41. package/dist/analyzer/parser.js.map +1 -0
  42. package/dist/analyzer/usage.d.ts +16 -0
  43. package/dist/analyzer/usage.js +159 -0
  44. package/dist/analyzer/usage.js.map +1 -0
  45. package/dist/ci/report.d.ts +88 -0
  46. package/dist/ci/report.js +139 -0
  47. package/dist/ci/report.js.map +1 -0
  48. package/dist/ci/run.d.ts +70 -0
  49. package/dist/ci/run.js +198 -0
  50. package/dist/ci/run.js.map +1 -0
  51. package/dist/ci/select.d.ts +58 -0
  52. package/dist/ci/select.js +238 -0
  53. package/dist/ci/select.js.map +1 -0
  54. package/dist/cli/commands/analyze.d.ts +2 -0
  55. package/dist/cli/commands/analyze.js +49 -0
  56. package/dist/cli/commands/analyze.js.map +1 -0
  57. package/dist/cli/commands/ci.d.ts +37 -0
  58. package/dist/cli/commands/ci.js +258 -0
  59. package/dist/cli/commands/ci.js.map +1 -0
  60. package/dist/cli/commands/generate.d.ts +3 -0
  61. package/dist/cli/commands/generate.js +201 -0
  62. package/dist/cli/commands/generate.js.map +1 -0
  63. package/dist/cli/commands/run.d.ts +4 -0
  64. package/dist/cli/commands/run.js +53 -0
  65. package/dist/cli/commands/run.js.map +1 -0
  66. package/dist/cli/index.d.ts +2 -0
  67. package/dist/cli/index.js +16 -0
  68. package/dist/cli/index.js.map +1 -0
  69. package/dist/cli/program.d.ts +2 -0
  70. package/dist/cli/program.js +20 -0
  71. package/dist/cli/program.js.map +1 -0
  72. package/dist/cli/report.d.ts +3 -0
  73. package/dist/cli/report.js +36 -0
  74. package/dist/cli/report.js.map +1 -0
  75. package/dist/cli/validateFile.d.ts +5 -0
  76. package/dist/cli/validateFile.js +43 -0
  77. package/dist/cli/validateFile.js.map +1 -0
  78. package/dist/errors.d.ts +4 -0
  79. package/dist/errors.js +8 -0
  80. package/dist/errors.js.map +1 -0
  81. package/dist/generator/diff.d.ts +5 -0
  82. package/dist/generator/diff.js +56 -0
  83. package/dist/generator/diff.js.map +1 -0
  84. package/dist/generator/importPlan.d.ts +15 -0
  85. package/dist/generator/importPlan.js +62 -0
  86. package/dist/generator/importPlan.js.map +1 -0
  87. package/dist/generator/index.d.ts +5 -0
  88. package/dist/generator/index.js +6 -0
  89. package/dist/generator/index.js.map +1 -0
  90. package/dist/generator/mocks.d.ts +48 -0
  91. package/dist/generator/mocks.js +356 -0
  92. package/dist/generator/mocks.js.map +1 -0
  93. package/dist/generator/schema.d.ts +40 -0
  94. package/dist/generator/schema.js +15 -0
  95. package/dist/generator/schema.js.map +1 -0
  96. package/dist/generator/testGenerator.d.ts +36 -0
  97. package/dist/generator/testGenerator.js +85 -0
  98. package/dist/generator/testGenerator.js.map +1 -0
  99. package/dist/generator/testWriter.d.ts +22 -0
  100. package/dist/generator/testWriter.js +93 -0
  101. package/dist/generator/testWriter.js.map +1 -0
  102. package/dist/generator/validate.d.ts +31 -0
  103. package/dist/generator/validate.js +180 -0
  104. package/dist/generator/validate.js.map +1 -0
  105. package/dist/repair/classifyFailure.d.ts +11 -0
  106. package/dist/repair/classifyFailure.js +26 -0
  107. package/dist/repair/classifyFailure.js.map +1 -0
  108. package/dist/repair/index.d.ts +2 -0
  109. package/dist/repair/index.js +3 -0
  110. package/dist/repair/index.js.map +1 -0
  111. package/dist/repair/repairLoop.d.ts +74 -0
  112. package/dist/repair/repairLoop.js +219 -0
  113. package/dist/repair/repairLoop.js.map +1 -0
  114. package/dist/repair/schema.d.ts +17 -0
  115. package/dist/repair/schema.js +14 -0
  116. package/dist/repair/schema.js.map +1 -0
  117. package/dist/runner/coverage.d.ts +5 -0
  118. package/dist/runner/coverage.js +42 -0
  119. package/dist/runner/coverage.js.map +1 -0
  120. package/dist/runner/index.d.ts +5 -0
  121. package/dist/runner/index.js +5 -0
  122. package/dist/runner/index.js.map +1 -0
  123. package/dist/runner/jestConfig.d.ts +11 -0
  124. package/dist/runner/jestConfig.js +103 -0
  125. package/dist/runner/jestConfig.js.map +1 -0
  126. package/dist/runner/jestRunner.d.ts +17 -0
  127. package/dist/runner/jestRunner.js +154 -0
  128. package/dist/runner/jestRunner.js.map +1 -0
  129. package/dist/runner/networkGuard.d.ts +4 -0
  130. package/dist/runner/networkGuard.js +55 -0
  131. package/dist/runner/networkGuard.js.map +1 -0
  132. package/dist/runner/project.d.ts +30 -0
  133. package/dist/runner/project.js +86 -0
  134. package/dist/runner/project.js.map +1 -0
  135. package/dist/runner/results.d.ts +32 -0
  136. package/dist/runner/results.js +58 -0
  137. package/dist/runner/results.js.map +1 -0
  138. package/dist/runner/types.d.ts +39 -0
  139. package/dist/runner/types.js +2 -0
  140. package/dist/runner/types.js.map +1 -0
  141. package/dist/runner/vitest.d.ts +24 -0
  142. package/dist/runner/vitest.js +105 -0
  143. package/dist/runner/vitest.js.map +1 -0
  144. package/dist/types/index.d.ts +96 -0
  145. package/dist/types/index.js +2 -0
  146. package/dist/types/index.js.map +1 -0
  147. package/package.json +67 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.js","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,oBAAoB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAElG,CAAC;AAEF,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE;SAC1B,IAAI,CAAC,YAAY,CAAC;SAClB,WAAW,CAAC,gFAAgF,CAAC;SAC7F,OAAO,CAAC,OAAO,CAAC;SAChB,kBAAkB,EAAE,CAAC;IAExB,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAE3B,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CoverageMetrics, RunResult } from "../runner/index.js";
2
+ export declare function formatCoverage(coverage: CoverageMetrics): string;
3
+ export declare function printRunResult(result: RunResult): void;
@@ -0,0 +1,36 @@
1
+ function pct(value) {
2
+ return value === null ? "n/a" : `${Math.round(value * 10) / 10}%`;
3
+ }
4
+ export function formatCoverage(coverage) {
5
+ return `${pct(coverage.lines)} lines, ${pct(coverage.branches)} branches, ${pct(coverage.functions)} functions`;
6
+ }
7
+ function firstLines(text, count) {
8
+ return text
9
+ .split("\n")
10
+ .filter((line) => line.trim())
11
+ .slice(0, count)
12
+ .map((line) => ` ${line.trim()}`)
13
+ .join("\n");
14
+ }
15
+ export function printRunResult(result) {
16
+ const seconds = (result.durationMs / 1000).toFixed(1);
17
+ if (result.sourceRestored)
18
+ console.log("! The tests modified the source file under test; Assertloom restored the original.");
19
+ if (result.infra) {
20
+ console.log(`✗ Jest could not run the tests (${result.infra.kind}, ${result.setup}, ${seconds}s)`);
21
+ console.log(firstLines(result.infra.message, 8));
22
+ return;
23
+ }
24
+ const skipped = result.skipped ? `, ${result.skipped} skipped` : "";
25
+ const mark = result.failed ? "!" : "✓";
26
+ console.log(`${mark} Ran Jest: ${result.passed} passed, ${result.failed} failed${skipped} (${result.setup}, ${seconds}s)`);
27
+ for (const test of result.tests) {
28
+ if (test.status !== "failed" || !test.failure)
29
+ continue;
30
+ console.log(` ✗ ${test.suite ? `${test.suite} › ` : ""}${test.name} [${test.failure.kind}]`);
31
+ console.log(firstLines(test.failure.message, 4));
32
+ }
33
+ if (result.coverage)
34
+ console.log(`✓ Coverage: ${formatCoverage(result.coverage)}`);
35
+ }
36
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/cli/report.ts"],"names":[],"mappings":"AAEA,SAAS,GAAG,CAAC,KAAoB;IAC/B,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAyB;IACtD,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC;AAClH,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,KAAa;IAC7C,OAAO,IAAI;SACR,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC7B,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;SACrC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAiB;IAC9C,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACtD,IAAI,MAAM,CAAC,cAAc;QAAE,OAAO,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAC;IAE7H,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,mCAAmC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,KAAK,OAAO,IAAI,CAAC,CAAC;QACnG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,cAAc,MAAM,CAAC,MAAM,YAAY,MAAM,CAAC,MAAM,UAAU,OAAO,KAAK,MAAM,CAAC,KAAK,KAAK,OAAO,IAAI,CAAC,CAAC;IAE3H,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,SAAS;QACxD,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;QAC/F,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ;QAAE,OAAO,CAAC,GAAG,CAAC,eAAe,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { UserError } from "../errors.js";
2
+ import { type SourceFile } from "../types/index.js";
3
+ export declare class FileValidationError extends UserError {
4
+ }
5
+ export declare function validateSourceFile(inputPath: string, cwd?: string): Promise<SourceFile>;
@@ -0,0 +1,43 @@
1
+ import { stat } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { UserError } from "../errors.js";
4
+ import { SUPPORTED_EXTENSIONS } from "../types/index.js";
5
+ export class FileValidationError extends UserError {
6
+ }
7
+ const MAX_FILE_SIZE_BYTES = 1024 * 1024;
8
+ function isSupportedExtension(ext) {
9
+ return SUPPORTED_EXTENSIONS.includes(ext);
10
+ }
11
+ export async function validateSourceFile(inputPath, cwd = process.cwd()) {
12
+ const absolutePath = path.resolve(cwd, inputPath);
13
+ const displayPath = path.relative(cwd, absolutePath) || inputPath;
14
+ const extension = path.extname(absolutePath).toLowerCase();
15
+ if (!isSupportedExtension(extension)) {
16
+ throw new FileValidationError(`Unsupported file type "${extension || "(none)"}" for ${displayPath}. ` +
17
+ `Supported extensions: ${SUPPORTED_EXTENSIONS.join(", ")}`);
18
+ }
19
+ if (/\.(test|spec)\.[cm]?[jt]sx?$/i.test(absolutePath)) {
20
+ throw new FileValidationError(`${displayPath} looks like a test file. Point Assertloom at source code instead.`);
21
+ }
22
+ let stats;
23
+ try {
24
+ stats = await stat(absolutePath);
25
+ }
26
+ catch {
27
+ throw new FileValidationError(`File not found: ${displayPath}`);
28
+ }
29
+ if (!stats.isFile()) {
30
+ throw new FileValidationError(`Not a file: ${displayPath}`);
31
+ }
32
+ if (stats.size > MAX_FILE_SIZE_BYTES) {
33
+ throw new FileValidationError(`${displayPath} is ${(stats.size / 1024).toFixed(0)} KB; files larger than 1 MB are not supported.`);
34
+ }
35
+ return {
36
+ inputPath: displayPath,
37
+ absolutePath,
38
+ extension,
39
+ language: /^\.[cm]?tsx?$/.test(extension) ? "typescript" : "javascript",
40
+ sizeBytes: stats.size,
41
+ };
42
+ }
43
+ //# sourceMappingURL=validateFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateFile.js","sourceRoot":"","sources":["../../src/cli/validateFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAA4C,MAAM,mBAAmB,CAAC;AAEnG,MAAM,OAAO,mBAAoB,SAAQ,SAAS;CAAG;AAErD,MAAM,mBAAmB,GAAG,IAAI,GAAG,IAAI,CAAC;AAExC,SAAS,oBAAoB,CAAC,GAAW;IACvC,OAAQ,oBAA0C,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,SAAiB,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAC7E,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,SAAS,CAAC;IAElE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3D,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,mBAAmB,CAC3B,0BAA0B,SAAS,IAAI,QAAQ,SAAS,WAAW,IAAI;YACrE,yBAAyB,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7D,CAAC;IACJ,CAAC;IAED,IAAI,+BAA+B,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,mBAAmB,CAAC,GAAG,WAAW,mEAAmE,CAAC,CAAC;IACnH,CAAC;IAED,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,mBAAmB,CAAC,mBAAmB,WAAW,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACpB,MAAM,IAAI,mBAAmB,CAAC,eAAe,WAAW,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,GAAG,mBAAmB,EAAE,CAAC;QACrC,MAAM,IAAI,mBAAmB,CAC3B,GAAG,WAAW,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,gDAAgD,CACpG,CAAC;IACJ,CAAC;IAED,OAAO;QACL,SAAS,EAAE,WAAW;QACtB,YAAY;QACZ,SAAS;QACT,QAAQ,EAAE,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY;QACvE,SAAS,EAAE,KAAK,CAAC,IAAI;KACtB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ /** An expected failure with a message fit to show the user as-is (no stack trace). */
2
+ export declare class UserError extends Error {
3
+ constructor(message: string);
4
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,8 @@
1
+ /** An expected failure with a message fit to show the user as-is (no stack trace). */
2
+ export class UserError extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = new.target.name;
6
+ }
7
+ }
8
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC;IAC9B,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ /** A unified line diff (`-` removed, `+` added) with `context` unchanged lines around each change. */
2
+ export declare function unifiedDiff(before: string, after: string, { context, maxLines }?: {
3
+ context?: number | undefined;
4
+ maxLines?: number | undefined;
5
+ }): string[];
@@ -0,0 +1,56 @@
1
+ /** Larger inputs get a one-line summary instead of a line diff, to bound memory. */
2
+ const MAX_DIFF_CELLS = 4_000_000;
3
+ /** A unified line diff (`-` removed, `+` added) with `context` unchanged lines around each change. */
4
+ export function unifiedDiff(before, after, { context = 3, maxLines = 120 } = {}) {
5
+ const a = before.split("\n");
6
+ const b = after.split("\n");
7
+ if (before === after)
8
+ return [];
9
+ if (a.length * b.length > MAX_DIFF_CELLS)
10
+ return [`(${a.length} lines → ${b.length} lines; too large to diff)`];
11
+ // lcs[i][j] = length of the longest common subsequence of a[i..] and b[j..].
12
+ const width = b.length + 1;
13
+ const lcs = new Uint32Array((a.length + 1) * width);
14
+ for (let i = a.length - 1; i >= 0; i--) {
15
+ for (let j = b.length - 1; j >= 0; j--) {
16
+ lcs[i * width + j] = a[i] === b[j] ? lcs[(i + 1) * width + j + 1] + 1 : Math.max(lcs[(i + 1) * width + j], lcs[i * width + j + 1]);
17
+ }
18
+ }
19
+ const ops = [];
20
+ let i = 0;
21
+ let j = 0;
22
+ while (i < a.length || j < b.length) {
23
+ if (i < a.length && j < b.length && a[i] === b[j])
24
+ ops.push({ kind: " ", text: a[i], oldLine: i++, newLine: j++ });
25
+ else if (i < a.length && (j === b.length || lcs[(i + 1) * width + j] >= lcs[i * width + j + 1]))
26
+ ops.push({ kind: "-", text: a[i], oldLine: i++, newLine: j });
27
+ else
28
+ ops.push({ kind: "+", text: b[j], oldLine: i, newLine: j++ });
29
+ }
30
+ const keep = ops.map(() => false);
31
+ ops.forEach((op, index) => {
32
+ if (op.kind === " ")
33
+ return;
34
+ for (let k = Math.max(0, index - context); k <= Math.min(ops.length - 1, index + context); k++)
35
+ keep[k] = true;
36
+ });
37
+ const lines = [];
38
+ for (let start = 0; start < ops.length; start++) {
39
+ if (!keep[start])
40
+ continue;
41
+ let end = start;
42
+ while (end + 1 < ops.length && keep[end + 1])
43
+ end++;
44
+ const hunk = ops.slice(start, end + 1);
45
+ const oldCount = hunk.filter((op) => op.kind !== "+").length;
46
+ const newCount = hunk.filter((op) => op.kind !== "-").length;
47
+ lines.push(`@@ -${hunk[0].oldLine + 1},${oldCount} +${hunk[0].newLine + 1},${newCount} @@`);
48
+ for (const op of hunk)
49
+ lines.push(`${op.kind}${op.text}`);
50
+ start = end;
51
+ }
52
+ if (lines.length > maxLines)
53
+ return [...lines.slice(0, maxLines), `… ${lines.length - maxLines} more diff lines`];
54
+ return lines;
55
+ }
56
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/generator/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { FileAnalysis, FunctionInfo } from "../types/index.js";
2
+ export interface Binding {
3
+ /** Name the test code uses to call the function. */
4
+ binding: string;
5
+ /** Exported name in the source module, or `"default"`. */
6
+ exportName: string;
7
+ fn: FunctionInfo;
8
+ }
9
+ export interface ImportPlan {
10
+ statements: string[];
11
+ bindings: Binding[];
12
+ }
13
+ /** Module specifier for importing `sourcePath` from a test file at `testPath`. */
14
+ export declare function importSpecifier(testPath: string, sourcePath: string): string;
15
+ export declare function planImports(analysis: FileAnalysis, functions: FunctionInfo[], sourcePath: string, testPath: string): ImportPlan;
@@ -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 { BudgetExceededError, 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 { BudgetExceededError, 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,mBAAmB,EAAE,aAAa,EAAE,eAAe,EAAyB,MAAM,oBAAoB,CAAC;AAChH,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>;