@devness/coverit 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 (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +169 -0
  3. package/dist/agents/orchestrator.d.ts +21 -0
  4. package/dist/agents/orchestrator.d.ts.map +1 -0
  5. package/dist/agents/orchestrator.js +235 -0
  6. package/dist/agents/orchestrator.js.map +1 -0
  7. package/dist/agents/reporter.d.ts +13 -0
  8. package/dist/agents/reporter.d.ts.map +1 -0
  9. package/dist/agents/reporter.js +323 -0
  10. package/dist/agents/reporter.js.map +1 -0
  11. package/dist/ai/anthropic-provider.d.ts +19 -0
  12. package/dist/ai/anthropic-provider.d.ts.map +1 -0
  13. package/dist/ai/anthropic-provider.js +83 -0
  14. package/dist/ai/anthropic-provider.js.map +1 -0
  15. package/dist/ai/claude-cli-provider.d.ts +22 -0
  16. package/dist/ai/claude-cli-provider.d.ts.map +1 -0
  17. package/dist/ai/claude-cli-provider.js +197 -0
  18. package/dist/ai/claude-cli-provider.js.map +1 -0
  19. package/dist/ai/index.d.ts +15 -0
  20. package/dist/ai/index.d.ts.map +1 -0
  21. package/dist/ai/index.js +16 -0
  22. package/dist/ai/index.js.map +1 -0
  23. package/dist/ai/ollama-provider.d.ts +17 -0
  24. package/dist/ai/ollama-provider.d.ts.map +1 -0
  25. package/dist/ai/ollama-provider.js +88 -0
  26. package/dist/ai/ollama-provider.js.map +1 -0
  27. package/dist/ai/openai-provider.d.ts +20 -0
  28. package/dist/ai/openai-provider.d.ts.map +1 -0
  29. package/dist/ai/openai-provider.js +74 -0
  30. package/dist/ai/openai-provider.js.map +1 -0
  31. package/dist/ai/prompts.d.ts +36 -0
  32. package/dist/ai/prompts.d.ts.map +1 -0
  33. package/dist/ai/prompts.js +259 -0
  34. package/dist/ai/prompts.js.map +1 -0
  35. package/dist/ai/provider-factory.d.ts +26 -0
  36. package/dist/ai/provider-factory.d.ts.map +1 -0
  37. package/dist/ai/provider-factory.js +111 -0
  38. package/dist/ai/provider-factory.js.map +1 -0
  39. package/dist/ai/types.d.ts +37 -0
  40. package/dist/ai/types.d.ts.map +1 -0
  41. package/dist/ai/types.js +10 -0
  42. package/dist/ai/types.js.map +1 -0
  43. package/dist/analysis/code-scanner.d.ts +9 -0
  44. package/dist/analysis/code-scanner.d.ts.map +1 -0
  45. package/dist/analysis/code-scanner.js +409 -0
  46. package/dist/analysis/code-scanner.js.map +1 -0
  47. package/dist/analysis/dependency-graph.d.ts +9 -0
  48. package/dist/analysis/dependency-graph.d.ts.map +1 -0
  49. package/dist/analysis/dependency-graph.js +149 -0
  50. package/dist/analysis/dependency-graph.js.map +1 -0
  51. package/dist/analysis/diff-analyzer.d.ts +9 -0
  52. package/dist/analysis/diff-analyzer.d.ts.map +1 -0
  53. package/dist/analysis/diff-analyzer.js +232 -0
  54. package/dist/analysis/diff-analyzer.js.map +1 -0
  55. package/dist/analysis/index.d.ts +5 -0
  56. package/dist/analysis/index.d.ts.map +1 -0
  57. package/dist/analysis/index.js +5 -0
  58. package/dist/analysis/index.js.map +1 -0
  59. package/dist/analysis/strategy-planner.d.ts +11 -0
  60. package/dist/analysis/strategy-planner.d.ts.map +1 -0
  61. package/dist/analysis/strategy-planner.js +384 -0
  62. package/dist/analysis/strategy-planner.js.map +1 -0
  63. package/dist/cli/index.d.ts +9 -0
  64. package/dist/cli/index.d.ts.map +1 -0
  65. package/dist/cli/index.js +288 -0
  66. package/dist/cli/index.js.map +1 -0
  67. package/dist/executors/base-executor.d.ts +35 -0
  68. package/dist/executors/base-executor.d.ts.map +1 -0
  69. package/dist/executors/base-executor.js +138 -0
  70. package/dist/executors/base-executor.js.map +1 -0
  71. package/dist/executors/browser-runner.d.ts +24 -0
  72. package/dist/executors/browser-runner.d.ts.map +1 -0
  73. package/dist/executors/browser-runner.js +194 -0
  74. package/dist/executors/browser-runner.js.map +1 -0
  75. package/dist/executors/cloud-runner.d.ts +41 -0
  76. package/dist/executors/cloud-runner.d.ts.map +1 -0
  77. package/dist/executors/cloud-runner.js +153 -0
  78. package/dist/executors/cloud-runner.js.map +1 -0
  79. package/dist/executors/index.d.ts +12 -0
  80. package/dist/executors/index.d.ts.map +1 -0
  81. package/dist/executors/index.js +28 -0
  82. package/dist/executors/index.js.map +1 -0
  83. package/dist/executors/local-runner.d.ts +40 -0
  84. package/dist/executors/local-runner.d.ts.map +1 -0
  85. package/dist/executors/local-runner.js +395 -0
  86. package/dist/executors/local-runner.js.map +1 -0
  87. package/dist/executors/reporter.d.ts +6 -0
  88. package/dist/executors/reporter.d.ts.map +1 -0
  89. package/dist/executors/reporter.js +6 -0
  90. package/dist/executors/reporter.js.map +1 -0
  91. package/dist/executors/simulator-runner.d.ts +30 -0
  92. package/dist/executors/simulator-runner.d.ts.map +1 -0
  93. package/dist/executors/simulator-runner.js +339 -0
  94. package/dist/executors/simulator-runner.js.map +1 -0
  95. package/dist/generators/api-test.d.ts +22 -0
  96. package/dist/generators/api-test.d.ts.map +1 -0
  97. package/dist/generators/api-test.js +235 -0
  98. package/dist/generators/api-test.js.map +1 -0
  99. package/dist/generators/base-generator.d.ts +79 -0
  100. package/dist/generators/base-generator.d.ts.map +1 -0
  101. package/dist/generators/base-generator.js +234 -0
  102. package/dist/generators/base-generator.js.map +1 -0
  103. package/dist/generators/desktop-test.d.ts +22 -0
  104. package/dist/generators/desktop-test.d.ts.map +1 -0
  105. package/dist/generators/desktop-test.js +290 -0
  106. package/dist/generators/desktop-test.js.map +1 -0
  107. package/dist/generators/e2e-browser.d.ts +19 -0
  108. package/dist/generators/e2e-browser.d.ts.map +1 -0
  109. package/dist/generators/e2e-browser.js +233 -0
  110. package/dist/generators/e2e-browser.js.map +1 -0
  111. package/dist/generators/index.d.ts +21 -0
  112. package/dist/generators/index.d.ts.map +1 -0
  113. package/dist/generators/index.js +66 -0
  114. package/dist/generators/index.js.map +1 -0
  115. package/dist/generators/mobile-test.d.ts +22 -0
  116. package/dist/generators/mobile-test.d.ts.map +1 -0
  117. package/dist/generators/mobile-test.js +286 -0
  118. package/dist/generators/mobile-test.js.map +1 -0
  119. package/dist/generators/unit-test.d.ts +23 -0
  120. package/dist/generators/unit-test.d.ts.map +1 -0
  121. package/dist/generators/unit-test.js +282 -0
  122. package/dist/generators/unit-test.js.map +1 -0
  123. package/dist/index.d.ts +12 -0
  124. package/dist/index.d.ts.map +1 -0
  125. package/dist/index.js +13 -0
  126. package/dist/index.js.map +1 -0
  127. package/dist/mcp/server.d.ts +8 -0
  128. package/dist/mcp/server.d.ts.map +1 -0
  129. package/dist/mcp/server.js +217 -0
  130. package/dist/mcp/server.js.map +1 -0
  131. package/dist/types/index.d.ts +295 -0
  132. package/dist/types/index.d.ts.map +1 -0
  133. package/dist/types/index.js +8 -0
  134. package/dist/types/index.js.map +1 -0
  135. package/dist/utils/framework-detector.d.ts +28 -0
  136. package/dist/utils/framework-detector.d.ts.map +1 -0
  137. package/dist/utils/framework-detector.js +184 -0
  138. package/dist/utils/framework-detector.js.map +1 -0
  139. package/dist/utils/git.d.ts +33 -0
  140. package/dist/utils/git.d.ts.map +1 -0
  141. package/dist/utils/git.js +82 -0
  142. package/dist/utils/git.js.map +1 -0
  143. package/dist/utils/logger.d.ts +17 -0
  144. package/dist/utils/logger.d.ts.map +1 -0
  145. package/dist/utils/logger.js +47 -0
  146. package/dist/utils/logger.js.map +1 -0
  147. package/package.json +86 -0
@@ -0,0 +1,286 @@
1
+ // Generated by coverit — https://coverit.dev
2
+ import { readFile } from "node:fs/promises";
3
+ import { dirname, join, relative } from "node:path";
4
+ import { BaseGenerator } from "./base-generator.js";
5
+ /**
6
+ * Generates React Native Testing Library tests for mobile screens and components,
7
+ * plus Detox E2E test stubs when the project uses Detox.
8
+ */
9
+ export class MobileTestGenerator extends BaseGenerator {
10
+ async generate(context) {
11
+ const { plan, project, scanResults, existingTests } = context;
12
+ const tests = [];
13
+ const warnings = [];
14
+ const skipped = [];
15
+ for (const scan of scanResults) {
16
+ if (!plan.target.files.includes(scan.file))
17
+ continue;
18
+ // ── AI-powered generation (preferred path) ──────────────
19
+ if (this.aiProvider) {
20
+ try {
21
+ const sourceCode = await readFile(join(project.root, scan.file), "utf-8");
22
+ const aiResult = await this.generateWithAI({
23
+ sourceCode,
24
+ scanResult: scan,
25
+ testType: "e2e-mobile",
26
+ framework: project.testFramework,
27
+ existingTests,
28
+ });
29
+ if (aiResult) {
30
+ const testFileName = this.generateTestFileName(scan.file, "e2e-mobile");
31
+ tests.push({
32
+ planId: plan.id,
33
+ filePath: testFileName,
34
+ content: aiResult,
35
+ testType: "e2e-mobile",
36
+ testCount: this.countTestCases(aiResult),
37
+ framework: project.testFramework === "detox"
38
+ ? "detox"
39
+ : project.testFramework,
40
+ });
41
+ continue; // Skip template fallback for this file
42
+ }
43
+ }
44
+ catch {
45
+ // Fall through to template-based generation
46
+ }
47
+ }
48
+ // ── Template-based generation (fallback) ────────────────
49
+ const components = scan.components;
50
+ if (components.length === 0) {
51
+ skipped.push({
52
+ target: scan.file,
53
+ reason: "No mobile components detected",
54
+ });
55
+ continue;
56
+ }
57
+ const testFileName = this.generateTestFileName(scan.file, "e2e-mobile");
58
+ const fw = project.testFramework;
59
+ // React Native Testing Library tests
60
+ const imports = this.buildMobileImports(scan, fw, testFileName);
61
+ const bodyBlocks = [];
62
+ let testCount = 0;
63
+ for (const component of components) {
64
+ if (this.isAlreadyTested(component.name, existingTests)) {
65
+ skipped.push({
66
+ target: component.name,
67
+ reason: "Already has mobile tests",
68
+ });
69
+ continue;
70
+ }
71
+ const cases = component.isPage
72
+ ? this.generateScreenTests(component)
73
+ : this.generateComponentTests(component);
74
+ bodyBlocks.push(this.buildDescribeBlock(component.name, cases));
75
+ testCount += cases.length;
76
+ }
77
+ if (testCount > 0) {
78
+ const content = this.assembleTestFile({
79
+ imports,
80
+ body: bodyBlocks,
81
+ });
82
+ tests.push({
83
+ planId: plan.id,
84
+ filePath: testFileName,
85
+ content,
86
+ testType: "e2e-mobile",
87
+ testCount,
88
+ framework: fw === "detox" ? "detox" : fw,
89
+ });
90
+ }
91
+ // Detox E2E stubs (if project uses Detox)
92
+ if (this.hasDetox(project)) {
93
+ const detoxResult = this.generateDetoxTests(scan, plan.id, existingTests);
94
+ if (detoxResult) {
95
+ tests.push(detoxResult);
96
+ testCount += detoxResult.testCount;
97
+ }
98
+ }
99
+ }
100
+ return { tests, warnings, skipped };
101
+ }
102
+ // ── Import generation ──────────────────────────────────────
103
+ buildMobileImports(scan, fw, testFilePath) {
104
+ const lines = [this.buildImports(fw)];
105
+ lines.push("import { render, screen, fireEvent, waitFor } from '@testing-library/react-native';");
106
+ // Import components under test
107
+ const componentNames = scan.components.map((c) => c.name);
108
+ const sourcePath = this.relativeImportPath(testFilePath, scan.file);
109
+ if (componentNames.length > 0) {
110
+ const named = componentNames.join(", ");
111
+ lines.push(`import { ${named} } from '${sourcePath}';`);
112
+ }
113
+ return lines;
114
+ }
115
+ // ── Screen tests (pages/routes) ────────────────────────────
116
+ generateScreenTests(component) {
117
+ const cases = [];
118
+ const propStr = this.buildDefaultProps(component.props);
119
+ // Renders without crashing
120
+ cases.push(this.buildTestCase("should render without crashing", [
121
+ `const { toJSON } = render(<${component.name}${propStr} />);`,
122
+ `expect(toJSON()).toBeTruthy();`,
123
+ ].join("\n")));
124
+ // Displays expected content
125
+ cases.push(this.buildTestCase("should display screen content", [
126
+ `render(<${component.name}${propStr} />);`,
127
+ `// Screen should render visible content`,
128
+ `expect(screen.toJSON()).toBeTruthy();`,
129
+ ].join("\n")));
130
+ // Navigation props test (React Navigation convention)
131
+ if (this.hasNavigationProp(component)) {
132
+ cases.push(this.buildTestCase("should accept navigation props", [
133
+ `const mockNavigation = { navigate: jest.fn(), goBack: jest.fn() };`,
134
+ `const mockRoute = { params: {} };`,
135
+ `render(<${component.name} navigation={mockNavigation as any} route={mockRoute as any} />);`,
136
+ `expect(screen.toJSON()).toBeTruthy();`,
137
+ ].join("\n")));
138
+ }
139
+ // Data display test
140
+ cases.push(this.buildAsyncTestCase("should handle loading and data states", [
141
+ `const { toJSON } = render(<${component.name}${propStr} />);`,
142
+ `// Initial render (possibly loading)`,
143
+ `expect(toJSON()).toBeTruthy();`,
144
+ `// Wait for async data if applicable`,
145
+ `await waitFor(() => {`,
146
+ ` expect(screen.toJSON()).toBeTruthy();`,
147
+ `});`,
148
+ ].join("\n")));
149
+ return cases;
150
+ }
151
+ // ── Component tests ────────────────────────────────────────
152
+ generateComponentTests(component) {
153
+ const cases = [];
154
+ const propStr = this.buildDefaultProps(component.props);
155
+ // Basic rendering
156
+ cases.push(this.buildTestCase("should render with required props", [
157
+ `const { toJSON } = render(<${component.name}${propStr} />);`,
158
+ `expect(toJSON()).toBeTruthy();`,
159
+ ].join("\n")));
160
+ // Event handler tests
161
+ const eventProps = component.props.filter((p) => /^on[A-Z]/.test(p.name));
162
+ for (const prop of eventProps) {
163
+ const eventName = prop.name.replace(/^on/, "").toLowerCase();
164
+ const mockName = `mock${prop.name.charAt(0).toUpperCase()}${prop.name.slice(1)}`;
165
+ cases.push(this.buildTestCase(`should call ${prop.name} handler`, [
166
+ `const ${mockName} = jest.fn();`,
167
+ `render(<${component.name}${propStr} ${prop.name}={${mockName}} />);`,
168
+ `// Trigger the ${eventName} event on the primary interactive element`,
169
+ `const target = screen.getByTestId('${this.toKebab(component.name)}');`,
170
+ `fireEvent.press(target);`,
171
+ `expect(${mockName}).toHaveBeenCalled();`,
172
+ ].join("\n")));
173
+ }
174
+ // Conditional rendering test for boolean props
175
+ const boolProps = component.props.filter((p) => p.type?.toLowerCase() === "boolean");
176
+ for (const prop of boolProps) {
177
+ cases.push(this.buildTestCase(`should handle ${prop.name} being false`, [
178
+ `const { toJSON } = render(<${component.name}${propStr} ${prop.name}={false} />);`,
179
+ `expect(toJSON()).toBeTruthy();`,
180
+ ].join("\n")));
181
+ }
182
+ // Snapshot-like structural test
183
+ cases.push(this.buildTestCase("should maintain consistent structure", [
184
+ `const { toJSON } = render(<${component.name}${propStr} />);`,
185
+ `expect(toJSON()).toMatchSnapshot();`,
186
+ ].join("\n")));
187
+ return cases;
188
+ }
189
+ // ── Detox E2E stubs ────────────────────────────────────────
190
+ generateDetoxTests(scan, planId, existingTests) {
191
+ const screens = scan.components.filter((c) => c.isPage);
192
+ if (screens.length === 0)
193
+ return null;
194
+ const testFileName = this.generateTestFileName(scan.file, "e2e-mobile")
195
+ .replace(".mobile.test.", ".detox.test.");
196
+ const imports = [
197
+ this.buildImports("detox"),
198
+ ];
199
+ const cases = [];
200
+ for (const screen of screens) {
201
+ if (this.isAlreadyTested(`detox:${screen.name}`, existingTests)) {
202
+ continue;
203
+ }
204
+ const screenCases = this.generateDetoxScreenTests(screen);
205
+ cases.push(this.buildDetoxDescribe(screen.name, screenCases));
206
+ }
207
+ if (cases.length === 0)
208
+ return null;
209
+ const beforeAll = [
210
+ "beforeAll(async () => {",
211
+ " await device.launchApp();",
212
+ "});",
213
+ "",
214
+ "beforeEach(async () => {",
215
+ " await device.reloadReactNative();",
216
+ "});",
217
+ ].join("\n");
218
+ const content = this.assembleTestFile({
219
+ imports,
220
+ body: [beforeAll, ...cases],
221
+ });
222
+ return {
223
+ planId,
224
+ filePath: testFileName,
225
+ content,
226
+ testType: "e2e-mobile",
227
+ testCount: cases.length,
228
+ framework: "detox",
229
+ };
230
+ }
231
+ generateDetoxScreenTests(screen) {
232
+ const testId = this.toKebab(screen.name);
233
+ const cases = [];
234
+ cases.push(this.buildDetoxTest("should be visible", [
235
+ `await detoxExpect(element(by.id('${testId}'))).toBeVisible();`,
236
+ ].join("\n")));
237
+ cases.push(this.buildDetoxTest("should respond to scroll", [
238
+ `await element(by.id('${testId}')).scroll(200, 'down');`,
239
+ `await detoxExpect(element(by.id('${testId}'))).toBeVisible();`,
240
+ ].join("\n")));
241
+ return cases;
242
+ }
243
+ buildDetoxDescribe(name, tests) {
244
+ const body = tests.map((t) => this.indent(t, 2)).join("\n\n");
245
+ return `describe('${this.escapeString(name)}', () => {\n${body}\n});`;
246
+ }
247
+ buildDetoxTest(name, body) {
248
+ const indentedBody = this.indent(body, 2);
249
+ return `it('${this.escapeString(name)}', async () => {\n${indentedBody}\n});`;
250
+ }
251
+ // ── Helpers ────────────────────────────────────────────────
252
+ hasDetox(project) {
253
+ return project.testFramework === "detox";
254
+ }
255
+ hasNavigationProp(component) {
256
+ return component.props.some((p) => p.name === "navigation" ||
257
+ p.name === "route" ||
258
+ p.type?.includes("NavigationProp") ||
259
+ p.type?.includes("RouteProp"));
260
+ }
261
+ buildDefaultProps(props) {
262
+ const required = props.filter((p) => !p.isOptional);
263
+ if (required.length === 0)
264
+ return "";
265
+ const propAssignments = required
266
+ .map((p) => {
267
+ if (/^on[A-Z]/.test(p.name))
268
+ return `${p.name}={jest.fn()}`;
269
+ return `${p.name}={${this.sampleValueForType(p.type)}}`;
270
+ })
271
+ .join(" ");
272
+ return ` ${propAssignments}`;
273
+ }
274
+ toKebab(name) {
275
+ return name
276
+ .replace(/([a-z])([A-Z])/g, "$1-$2")
277
+ .replace(/([A-Z])([A-Z][a-z])/g, "$1-$2")
278
+ .toLowerCase();
279
+ }
280
+ relativeImportPath(from, to) {
281
+ const rel = relative(dirname(from), to);
282
+ const withoutExt = rel.replace(/\.(ts|tsx|js|jsx)$/, "");
283
+ return rel.startsWith(".") ? withoutExt : `./${withoutExt}`;
284
+ }
285
+ }
286
+ //# sourceMappingURL=mobile-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mobile-test.js","sourceRoot":"","sources":["../../src/generators/mobile-test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { GeneratorContext, GeneratorResult } from "../types/index.js";
2
+ import { BaseGenerator } from "./base-generator.js";
3
+ /**
4
+ * Generates unit tests for pure functions, class methods, and utility modules.
5
+ * Supports Vitest and Jest output with idiomatic mocking patterns.
6
+ */
7
+ export declare class UnitTestGenerator extends BaseGenerator {
8
+ private isIntegration;
9
+ setIntegrationMode(flag: boolean): void;
10
+ generate(context: GeneratorContext): Promise<GeneratorResult>;
11
+ private buildFileImports;
12
+ private buildMock;
13
+ private generateFunctionTests;
14
+ private happyPathTest;
15
+ private edgeCaseTests;
16
+ private edgeCaseTest;
17
+ private returnTypeTest;
18
+ private errorThrowingTest;
19
+ private generateClassTests;
20
+ private generateMethodTests;
21
+ private relativeImportPath;
22
+ }
23
+ //# sourceMappingURL=unit-test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unit-test.d.ts","sourceRoot":"","sources":["../../src/generators/unit-test.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAKV,gBAAgB,EAChB,eAAe,EAKhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,aAAa;IAClD,OAAO,CAAC,aAAa,CAAS;IAE9B,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAIjC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAsHnE,OAAO,CAAC,gBAAgB;IAqCxB,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,qBAAqB;IA2B7B,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,aAAa;IAmCrB,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,kBAAkB;IAsB1B,OAAO,CAAC,mBAAmB;IA0C3B,OAAO,CAAC,kBAAkB;CAK3B"}
@@ -0,0 +1,282 @@
1
+ // Generated by coverit — https://coverit.dev
2
+ import { readFile } from "node:fs/promises";
3
+ import { dirname, join, relative } from "node:path";
4
+ import { BaseGenerator } from "./base-generator.js";
5
+ /**
6
+ * Generates unit tests for pure functions, class methods, and utility modules.
7
+ * Supports Vitest and Jest output with idiomatic mocking patterns.
8
+ */
9
+ export class UnitTestGenerator extends BaseGenerator {
10
+ isIntegration = false;
11
+ setIntegrationMode(flag) {
12
+ this.isIntegration = flag;
13
+ }
14
+ async generate(context) {
15
+ const { plan, project, scanResults, existingTests } = context;
16
+ const tests = [];
17
+ const warnings = [];
18
+ const skipped = [];
19
+ const testType = this.isIntegration ? "integration" : "unit";
20
+ for (const scan of scanResults) {
21
+ if (!plan.target.files.includes(scan.file))
22
+ continue;
23
+ // ── AI-powered generation (preferred path) ──────────────
24
+ if (this.aiProvider) {
25
+ try {
26
+ const sourceCode = await readFile(join(project.root, scan.file), "utf-8");
27
+ const aiResult = await this.generateWithAI({
28
+ sourceCode,
29
+ scanResult: scan,
30
+ testType,
31
+ framework: project.testFramework,
32
+ existingTests,
33
+ });
34
+ if (aiResult) {
35
+ const testFileName = this.generateTestFileName(scan.file, testType);
36
+ tests.push({
37
+ planId: plan.id,
38
+ filePath: testFileName,
39
+ content: aiResult,
40
+ testType,
41
+ testCount: this.countTestCases(aiResult),
42
+ framework: project.testFramework === "playwright" ||
43
+ project.testFramework === "detox"
44
+ ? "vitest"
45
+ : project.testFramework,
46
+ });
47
+ continue; // Skip template fallback for this file
48
+ }
49
+ }
50
+ catch {
51
+ // Fall through to template-based generation
52
+ }
53
+ }
54
+ // ── Template-based generation (fallback) ────────────────
55
+ const functions = scan.functions.filter((f) => f.isExported);
56
+ const classes = scan.classes.filter((c) => c.isExported);
57
+ if (functions.length === 0 && classes.length === 0) {
58
+ skipped.push({
59
+ target: scan.file,
60
+ reason: "No exported functions or classes found",
61
+ });
62
+ continue;
63
+ }
64
+ const testFileName = this.generateTestFileName(scan.file, testType);
65
+ const fw = project.testFramework;
66
+ const imports = this.buildFileImports(scan, fw, testFileName);
67
+ const bodyBlocks = [];
68
+ let testCount = 0;
69
+ // Generate tests for standalone functions
70
+ for (const fn of functions) {
71
+ if (this.isAlreadyTested(fn.name, existingTests)) {
72
+ skipped.push({
73
+ target: `${scan.file}:${fn.name}`,
74
+ reason: "Already has tests",
75
+ });
76
+ continue;
77
+ }
78
+ const cases = this.generateFunctionTests(fn, fw);
79
+ bodyBlocks.push(this.buildDescribeBlock(fn.name, cases));
80
+ testCount += cases.length;
81
+ }
82
+ // Generate tests for class methods
83
+ for (const cls of classes) {
84
+ if (this.isAlreadyTested(cls.name, existingTests)) {
85
+ skipped.push({
86
+ target: `${scan.file}:${cls.name}`,
87
+ reason: "Already has tests",
88
+ });
89
+ continue;
90
+ }
91
+ const classCases = this.generateClassTests(cls, fw);
92
+ bodyBlocks.push(this.buildDescribeBlock(cls.name, classCases));
93
+ testCount += classCases.length;
94
+ }
95
+ if (testCount === 0)
96
+ continue;
97
+ const content = this.assembleTestFile({
98
+ imports,
99
+ body: bodyBlocks,
100
+ });
101
+ tests.push({
102
+ planId: plan.id,
103
+ filePath: testFileName,
104
+ content,
105
+ testType,
106
+ testCount,
107
+ framework: fw === "playwright" || fw === "detox" ? "vitest" : fw,
108
+ });
109
+ }
110
+ return { tests, warnings, skipped };
111
+ }
112
+ // ── Import generation ──────────────────────────────────────
113
+ buildFileImports(scan, fw, testFilePath) {
114
+ const lines = [this.buildImports(fw)];
115
+ // Import the source module under test
116
+ const defaultExport = scan.exports.find((e) => e.isDefault);
117
+ const namedExports = scan.exports.filter((e) => !e.isDefault && (e.kind === "function" || e.kind === "class"));
118
+ const sourcePath = this.relativeImportPath(testFilePath, scan.file);
119
+ if (defaultExport && namedExports.length > 0) {
120
+ const named = namedExports.map((e) => e.name).join(", ");
121
+ lines.push(`import ${defaultExport.name}, { ${named} } from '${sourcePath}';`);
122
+ }
123
+ else if (defaultExport) {
124
+ lines.push(`import ${defaultExport.name} from '${sourcePath}';`);
125
+ }
126
+ else if (namedExports.length > 0) {
127
+ const named = namedExports.map((e) => e.name).join(", ");
128
+ lines.push(`import { ${named} } from '${sourcePath}';`);
129
+ }
130
+ // Mock external dependencies
131
+ const externalDeps = scan.imports.filter((m) => m.isExternal);
132
+ for (const dep of externalDeps) {
133
+ lines.push(this.buildMock(dep, fw));
134
+ }
135
+ return lines;
136
+ }
137
+ buildMock(dep, fw) {
138
+ const mockFn = fw === "vitest" ? "vi.mock" : "jest.mock";
139
+ if (dep.specifiers.length === 0) {
140
+ return `${mockFn}('${dep.source}');`;
141
+ }
142
+ const specs = dep.specifiers
143
+ .map((s) => ` ${s}: ${fw === "vitest" ? "vi.fn()" : "jest.fn()"},`)
144
+ .join("\n");
145
+ return `${mockFn}('${dep.source}', () => ({\n${specs}\n}));`;
146
+ }
147
+ // ── Function test generation ───────────────────────────────
148
+ generateFunctionTests(fn, fw) {
149
+ const cases = [];
150
+ // Happy path
151
+ cases.push(this.happyPathTest(fn, fw));
152
+ // Edge cases for each parameter
153
+ for (const param of fn.params) {
154
+ cases.push(...this.edgeCaseTests(fn, param, fw));
155
+ }
156
+ // Zero-arg functions get a basic invocation test only
157
+ if (fn.params.length === 0 && cases.length === 1) {
158
+ cases.push(this.returnTypeTest(fn));
159
+ }
160
+ // Error-throwing case if complexity is high
161
+ if (fn.complexity > 3) {
162
+ cases.push(this.errorThrowingTest(fn, fw));
163
+ }
164
+ return cases;
165
+ }
166
+ happyPathTest(fn, _fw) {
167
+ const args = fn.params.map((p) => this.sampleValueForType(p.type)).join(", ");
168
+ const call = fn.isAsync
169
+ ? `await ${fn.name}(${args})`
170
+ : `${fn.name}(${args})`;
171
+ const assertion = fn.returnType
172
+ ? `expect(result).toBeDefined();`
173
+ : `expect(result).toBeUndefined();`;
174
+ const body = `const result = ${call};\n${assertion}`;
175
+ return fn.isAsync
176
+ ? this.buildAsyncTestCase(`should return expected result`, body)
177
+ : this.buildTestCase(`should return expected result`, body);
178
+ }
179
+ edgeCaseTests(fn, param, _fw) {
180
+ const cases = [];
181
+ const type = (param.type ?? "").toLowerCase();
182
+ if (type === "string" || !param.type) {
183
+ cases.push(this.edgeCaseTest(fn, param, "''", "empty string"));
184
+ }
185
+ if (type === "number") {
186
+ cases.push(this.edgeCaseTest(fn, param, "0", "zero"));
187
+ cases.push(this.edgeCaseTest(fn, param, "-1", "negative number"));
188
+ cases.push(this.edgeCaseTest(fn, param, "Number.MAX_SAFE_INTEGER", "max safe integer"));
189
+ }
190
+ if (type === "boolean") {
191
+ cases.push(this.edgeCaseTest(fn, param, "false", "false"));
192
+ }
193
+ if (type.endsWith("[]")) {
194
+ cases.push(this.edgeCaseTest(fn, param, "[]", "empty array"));
195
+ }
196
+ if (param.isOptional) {
197
+ cases.push(this.edgeCaseTest(fn, param, "undefined", "undefined"));
198
+ }
199
+ return cases;
200
+ }
201
+ edgeCaseTest(fn, targetParam, edgeValue, label) {
202
+ const args = fn.params
203
+ .map((p) => p.name === targetParam.name
204
+ ? edgeValue
205
+ : this.sampleValueForType(p.type))
206
+ .join(", ");
207
+ const call = fn.isAsync
208
+ ? `await ${fn.name}(${args})`
209
+ : `${fn.name}(${args})`;
210
+ const body = `const result = ${call};\nexpect(result).toBeDefined();`;
211
+ const name = `should handle ${label} for ${targetParam.name}`;
212
+ return fn.isAsync
213
+ ? this.buildAsyncTestCase(name, body)
214
+ : this.buildTestCase(name, body);
215
+ }
216
+ returnTypeTest(fn) {
217
+ const call = fn.isAsync ? `await ${fn.name}()` : `${fn.name}()`;
218
+ const body = `const result = ${call};\nexpect(result).toBeDefined();`;
219
+ return fn.isAsync
220
+ ? this.buildAsyncTestCase("should return a defined value", body)
221
+ : this.buildTestCase("should return a defined value", body);
222
+ }
223
+ errorThrowingTest(fn, _fw) {
224
+ // Generate null args to provoke error paths
225
+ const args = fn.params.map(() => "null as any").join(", ");
226
+ const body = fn.isAsync
227
+ ? `await expect(${fn.name}(${args})).rejects.toThrow();`
228
+ : `expect(() => ${fn.name}(${args})).toThrow();`;
229
+ const name = "should throw on invalid input";
230
+ return fn.isAsync
231
+ ? this.buildAsyncTestCase(name, body)
232
+ : this.buildTestCase(name, body);
233
+ }
234
+ // ── Class test generation ──────────────────────────────────
235
+ generateClassTests(cls, fw) {
236
+ const cases = [];
237
+ // Constructor / instantiation test
238
+ cases.push(this.buildTestCase("should be instantiable", `const instance = new ${cls.name}();\nexpect(instance).toBeInstanceOf(${cls.name});`));
239
+ // Public methods
240
+ const publicMethods = cls.methods.filter((m) => !m.name.startsWith("_") && !m.name.startsWith("#"));
241
+ for (const method of publicMethods) {
242
+ const methodCases = this.generateMethodTests(cls.name, method, fw);
243
+ // Wrap method cases in a nested describe
244
+ cases.push(this.buildDescribeBlock(method.name, methodCases));
245
+ }
246
+ return cases;
247
+ }
248
+ generateMethodTests(className, method, _fw) {
249
+ const cases = [];
250
+ const args = method.params
251
+ .map((p) => this.sampleValueForType(p.type))
252
+ .join(", ");
253
+ const call = method.isAsync
254
+ ? `await instance.${method.name}(${args})`
255
+ : `instance.${method.name}(${args})`;
256
+ const happyBody = `const instance = new ${className}();\nconst result = ${call};\nexpect(result).toBeDefined();`;
257
+ cases.push(method.isAsync
258
+ ? this.buildAsyncTestCase("should execute successfully", happyBody)
259
+ : this.buildTestCase("should execute successfully", happyBody));
260
+ // Edge case for methods with params
261
+ if (method.params.length > 0) {
262
+ const nullArgs = method.params.map(() => "null as any").join(", ");
263
+ const errorCall = method.isAsync
264
+ ? `await instance.${method.name}(${nullArgs})`
265
+ : `instance.${method.name}(${nullArgs})`;
266
+ const errorBody = method.isAsync
267
+ ? `const instance = new ${className}();\nawait expect(async () => ${errorCall}).rejects.toThrow();`
268
+ : `const instance = new ${className}();\nexpect(() => ${errorCall}).toThrow();`;
269
+ cases.push(method.isAsync
270
+ ? this.buildAsyncTestCase("should handle invalid input", errorBody)
271
+ : this.buildTestCase("should handle invalid input", errorBody));
272
+ }
273
+ return cases;
274
+ }
275
+ // ── Helpers ────────────────────────────────────────────────
276
+ relativeImportPath(from, to) {
277
+ const rel = relative(dirname(from), to);
278
+ const withoutExt = rel.replace(/\.(ts|tsx|js|jsx)$/, "");
279
+ return rel.startsWith(".") ? withoutExt : `./${withoutExt}`;
280
+ }
281
+ }
282
+ //# sourceMappingURL=unit-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unit-test.js","sourceRoot":"","sources":["../../src/generators/unit-test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Coverit — Public API
3
+ *
4
+ * Re-exports the orchestrator, types, and utility modules
5
+ * for programmatic usage as a library.
6
+ */
7
+ export { orchestrate } from "./agents/orchestrator.js";
8
+ export type { DiffResult, ChangedFile, DiffHunk, Language, FileType, CodeScanResult, ExportedSymbol, ImportedModule, FunctionInfo, ParamInfo, ClassInfo, PropertyInfo, EndpointInfo, ComponentInfo, DependencyNode, DependencyGraph, TestStrategy, ProjectInfo, Framework, TestFramework, PackageManager, TestPlan, TestType, TestTarget, ExecutionPhase, ExecutionEnvironment, GeneratedTest, GeneratorContext, GeneratorResult, SkippedItem, ExecutionConfig, CloudConfig, ExecutionResult, CoverageResult, CoverageMetric, TestFailure, CoveritReport, ReportSummary, TypeSummary, CoveritConfig, CoveritEvent, CoveritEventHandler, } from "./types/index.js";
9
+ export { getChangedFiles, getDiff, getCurrentBranch, getBaseBranch, isGitRepo, getStagedFiles, } from "./utils/git.js";
10
+ export { detectFramework, detectTestFramework, detectPackageManager, detectProjectInfo, } from "./utils/framework-detector.js";
11
+ export { logger } from "./utils/logger.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,YAAY,EAEV,UAAU,EACV,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,SAAS,EACT,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,aAAa,EAEb,cAAc,EACd,eAAe,EAEf,YAAY,EACZ,WAAW,EACX,SAAS,EACT,aAAa,EACb,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,cAAc,EACd,oBAAoB,EAEpB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,WAAW,EAEX,eAAe,EACf,WAAW,EACX,eAAe,EACf,cAAc,EACd,cAAc,EACd,WAAW,EAEX,aAAa,EACb,aAAa,EACb,WAAW,EAEX,aAAa,EACb,YAAY,EACZ,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,eAAe,EACf,OAAO,EACP,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC"}