@theihtisham/ai-testgen 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +383 -0
- package/dist/analyzers/analyzer.d.ts +10 -0
- package/dist/analyzers/analyzer.d.ts.map +1 -0
- package/dist/analyzers/analyzer.js +131 -0
- package/dist/analyzers/analyzer.js.map +1 -0
- package/dist/analyzers/go-analyzer.d.ts +3 -0
- package/dist/analyzers/go-analyzer.d.ts.map +1 -0
- package/dist/analyzers/go-analyzer.js +244 -0
- package/dist/analyzers/go-analyzer.js.map +1 -0
- package/dist/analyzers/index.d.ts +5 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +15 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/js-ts-analyzer.d.ts +3 -0
- package/dist/analyzers/js-ts-analyzer.d.ts.map +1 -0
- package/dist/analyzers/js-ts-analyzer.js +299 -0
- package/dist/analyzers/js-ts-analyzer.js.map +1 -0
- package/dist/analyzers/python-analyzer.d.ts +3 -0
- package/dist/analyzers/python-analyzer.d.ts.map +1 -0
- package/dist/analyzers/python-analyzer.js +306 -0
- package/dist/analyzers/python-analyzer.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +381 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/defaults.d.ts +6 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +80 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +14 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +6 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +126 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/coverage.d.ts +4 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +108 -0
- package/dist/coverage.js.map +1 -0
- package/dist/generators/ai-generator.d.ts +4 -0
- package/dist/generators/ai-generator.d.ts.map +1 -0
- package/dist/generators/ai-generator.js +175 -0
- package/dist/generators/ai-generator.js.map +1 -0
- package/dist/generators/generator.d.ts +4 -0
- package/dist/generators/generator.d.ts.map +1 -0
- package/dist/generators/generator.js +121 -0
- package/dist/generators/generator.js.map +1 -0
- package/dist/generators/go-generator.d.ts +3 -0
- package/dist/generators/go-generator.d.ts.map +1 -0
- package/dist/generators/go-generator.js +175 -0
- package/dist/generators/go-generator.js.map +1 -0
- package/dist/generators/index.d.ts +6 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +16 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/js-ts-generator.d.ts +3 -0
- package/dist/generators/js-ts-generator.d.ts.map +1 -0
- package/dist/generators/js-ts-generator.js +331 -0
- package/dist/generators/js-ts-generator.js.map +1 -0
- package/dist/generators/python-generator.d.ts +3 -0
- package/dist/generators/python-generator.d.ts.map +1 -0
- package/dist/generators/python-generator.js +180 -0
- package/dist/generators/python-generator.js.map +1 -0
- package/dist/incremental.d.ts +16 -0
- package/dist/incremental.d.ts.map +1 -0
- package/dist/incremental.js +146 -0
- package/dist/incremental.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/mutation/index.d.ts +2 -0
- package/dist/mutation/index.d.ts.map +1 -0
- package/dist/mutation/index.js +9 -0
- package/dist/mutation/index.js.map +1 -0
- package/dist/mutation/mutator.d.ts +6 -0
- package/dist/mutation/mutator.d.ts.map +1 -0
- package/dist/mutation/mutator.js +237 -0
- package/dist/mutation/mutator.js.map +1 -0
- package/dist/types.d.ts +199 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/file.d.ts +10 -0
- package/dist/utils/file.d.ts.map +1 -0
- package/dist/utils/file.js +108 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +24 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/language.d.ts +8 -0
- package/dist/utils/language.d.ts.map +1 -0
- package/dist/utils/language.js +137 -0
- package/dist/utils/language.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +57 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/watcher/index.d.ts +2 -0
- package/dist/watcher/index.d.ts.map +1 -0
- package/dist/watcher/index.js +6 -0
- package/dist/watcher/index.js.map +1 -0
- package/dist/watcher/watcher.d.ts +19 -0
- package/dist/watcher/watcher.d.ts.map +1 -0
- package/dist/watcher/watcher.js +122 -0
- package/dist/watcher/watcher.js.map +1 -0
- package/package.json +63 -0
- package/src/analyzers/analyzer.ts +180 -0
- package/src/analyzers/go-analyzer.ts +235 -0
- package/src/analyzers/index.ts +4 -0
- package/src/analyzers/js-ts-analyzer.ts +324 -0
- package/src/analyzers/python-analyzer.ts +306 -0
- package/src/cli.ts +416 -0
- package/src/config/defaults.ts +81 -0
- package/src/config/index.ts +2 -0
- package/src/config/loader.ts +114 -0
- package/src/coverage.ts +128 -0
- package/src/generators/ai-generator.ts +170 -0
- package/src/generators/generator.ts +117 -0
- package/src/generators/go-generator.ts +183 -0
- package/src/generators/index.ts +5 -0
- package/src/generators/js-ts-generator.ts +379 -0
- package/src/generators/python-generator.ts +201 -0
- package/src/incremental.ts +131 -0
- package/src/index.ts +8 -0
- package/src/mutation/index.ts +1 -0
- package/src/mutation/mutator.ts +314 -0
- package/src/types.ts +240 -0
- package/src/utils/file.ts +73 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/language.ts +114 -0
- package/src/utils/logger.ts +61 -0
- package/src/watcher/index.ts +1 -0
- package/src/watcher/watcher.ts +103 -0
- package/tests/analyzer.test.ts +429 -0
- package/tests/config.test.ts +171 -0
- package/tests/coverage.test.ts +197 -0
- package/tests/file-utils.test.ts +121 -0
- package/tests/generators.test.ts +383 -0
- package/tests/incremental.test.ts +108 -0
- package/tests/language.test.ts +90 -0
- package/tests/mutation.test.ts +286 -0
- package/tests/watcher.test.ts +35 -0
- package/tsconfig.json +26 -0
- package/vitest.config.ts +25 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://img.shields.io/badge/AI--TestGen-v1.0.0-blue" alt="Version" />
|
|
3
|
+
<img src="https://img.shields.io/badge/license-MIT-green" alt="License" />
|
|
4
|
+
<img src="https://img.shields.io/badge/node-%3E%3D18-brightgreen" alt="Node" />
|
|
5
|
+
<img src="https://img.shields.io/badge/tests-passing-brightgreen" alt="Tests" />
|
|
6
|
+
<img src="https://img.shields.io/badge/coverage-90%25+-success" alt="Coverage" />
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<h1 align="center">AI-TestGen</h1>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<strong>Stop writing tests. AI reads your code and generates comprehensive test suites — 90% coverage in 10 seconds.</strong>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="#features">Features</a> ·
|
|
17
|
+
<a href="#installation">Install</a> ·
|
|
18
|
+
<a href="#quick-start">Quick Start</a> ·
|
|
19
|
+
<a href="#before--after">Before / After</a> ·
|
|
20
|
+
<a href="#configuration">Configuration</a> ·
|
|
21
|
+
<a href="#cli-reference">CLI</a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
### Language Support
|
|
29
|
+
- **TypeScript / JavaScript** — Full AST analysis via ts-morph, generates Jest or Vitest test suites
|
|
30
|
+
- **Python** — Regex-based AST analysis, generates pytest test suites
|
|
31
|
+
- **Go** — Struct-aware analysis, generates `go test` compatible files
|
|
32
|
+
- **Rust** — AI-powered generation (coming soon)
|
|
33
|
+
- Auto-detects language from file extension
|
|
34
|
+
|
|
35
|
+
### Test Generation
|
|
36
|
+
- **Unit Tests** — Happy path, type checks, return value verification
|
|
37
|
+
- **Integration Tests** — Cross-module dependency analysis
|
|
38
|
+
- **Edge Case Tests** — Null/undefined, empty arrays, boundary values, NaN, Infinity, special characters
|
|
39
|
+
- **Error Path Tests** — Exception handling, error boundaries, async rejections
|
|
40
|
+
- **Mock Setup** — Auto-generated mocks for external dependencies
|
|
41
|
+
|
|
42
|
+
### Advanced Features
|
|
43
|
+
- **Mutation Testing** — Generates code mutants (arithmetic, comparison, logical, boolean, string) to verify test quality
|
|
44
|
+
- **Coverage Prediction** — Estimates line, branch, and function coverage before running tests
|
|
45
|
+
- **Multi-file Analysis** — Builds dependency graphs across your codebase
|
|
46
|
+
- **Incremental Mode** — Only generates tests for changed files (git-based or hash-based)
|
|
47
|
+
- **Watch Mode** — Auto-generate tests on file save with configurable debounce
|
|
48
|
+
- **AI Enhancement** — Optional OpenAI integration for smarter test generation
|
|
49
|
+
- **Privacy Mode** — Sends only analysis metadata to AI, never raw source code
|
|
50
|
+
|
|
51
|
+
### Security First
|
|
52
|
+
- No code sent to external APIs unless explicitly configured
|
|
53
|
+
- Local AST analysis is the default
|
|
54
|
+
- API keys via environment variables only
|
|
55
|
+
- Privacy mode strips source code before AI calls
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Clone and install
|
|
61
|
+
git clone https://github.com/yourusername/ai-testgen.git
|
|
62
|
+
cd ai-testgen
|
|
63
|
+
npm install
|
|
64
|
+
npm run build
|
|
65
|
+
|
|
66
|
+
# Use globally
|
|
67
|
+
npm link
|
|
68
|
+
ai-testgen generate ./src
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Quick Start
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Generate tests for a single file
|
|
75
|
+
ai-testgen generate src/utils/math.ts
|
|
76
|
+
|
|
77
|
+
# Generate tests for an entire directory
|
|
78
|
+
ai-testgen generate src/
|
|
79
|
+
|
|
80
|
+
# Generate with coverage prediction
|
|
81
|
+
ai-testgen generate src/ --coverage
|
|
82
|
+
|
|
83
|
+
# Generate with mutation testing
|
|
84
|
+
ai-testgen generate src/ --mutation
|
|
85
|
+
|
|
86
|
+
# Dry run (see what would be generated)
|
|
87
|
+
ai-testgen generate src/ --dry-run
|
|
88
|
+
|
|
89
|
+
# Initialize a config file
|
|
90
|
+
ai-testgen init
|
|
91
|
+
|
|
92
|
+
# Analyze code without generating tests
|
|
93
|
+
ai-testgen analyze src/utils.ts
|
|
94
|
+
|
|
95
|
+
# Watch mode (auto-regenerate on save)
|
|
96
|
+
ai-testgen watch src/
|
|
97
|
+
|
|
98
|
+
# Mutation testing only
|
|
99
|
+
ai-testgen mutation src/utils.ts
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Before / After
|
|
103
|
+
|
|
104
|
+
### Before (your source code)
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// src/calculator.ts
|
|
108
|
+
export function divide(a: number, b: number): number {
|
|
109
|
+
if (b === 0) {
|
|
110
|
+
throw new Error('Division by zero');
|
|
111
|
+
}
|
|
112
|
+
return a / b;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export class Calculator {
|
|
116
|
+
private history: number[] = [];
|
|
117
|
+
|
|
118
|
+
add(a: number, b: number): number {
|
|
119
|
+
const result = a + b;
|
|
120
|
+
this.history.push(result);
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async fetchRate(currency: string): Promise<number> {
|
|
125
|
+
const response = await fetch(`/api/rates/${currency}`);
|
|
126
|
+
return response.json();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### After (auto-generated tests)
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// __tests__/calculator.test.ts
|
|
135
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
136
|
+
import { divide, Calculator } from './calculator';
|
|
137
|
+
|
|
138
|
+
vi.mock('/api/rates/USD');
|
|
139
|
+
|
|
140
|
+
describe('calculator', () => {
|
|
141
|
+
beforeEach(() => {
|
|
142
|
+
vi.clearAllMocks();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
afterEach(() => {
|
|
146
|
+
vi.clearAllMocks();
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
describe('divide', () => {
|
|
150
|
+
it('divide returns expected result for valid input', () => {
|
|
151
|
+
const result = divide(42, 42);
|
|
152
|
+
expect(result).toBeDefined();
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('divide returns correct type', () => {
|
|
156
|
+
const result = divide(42, 42);
|
|
157
|
+
expect(typeof result).toBeDefined();
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('divide throws on invalid input', () => {
|
|
161
|
+
expect(() => divide('not-a-number', null)).toThrow();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('divide handles zero for b', () => {
|
|
165
|
+
// edge case: zero value
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('divide handles NaN for a', () => {
|
|
169
|
+
// edge case: NaN
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('divide handles negative number for b', () => {
|
|
173
|
+
// edge case: negative numbers
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
describe('Calculator', () => {
|
|
178
|
+
it('Calculator can be instantiated', () => {
|
|
179
|
+
const instance = new Calculator();
|
|
180
|
+
expect(instance).toBeInstanceOf(Calculator);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('Calculator.add works correctly', () => {
|
|
184
|
+
const instance = new Calculator();
|
|
185
|
+
const result = instance.add(42, 42);
|
|
186
|
+
expect(result).toBeDefined();
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('Calculator.fetchRate handles async correctly', () => {
|
|
190
|
+
const instance = new Calculator();
|
|
191
|
+
const result = await instance.fetchRate('test-currency');
|
|
192
|
+
expect(result).toBeDefined();
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Configuration
|
|
199
|
+
|
|
200
|
+
Create `.aitestgen.yml` in your project root:
|
|
201
|
+
|
|
202
|
+
```yaml
|
|
203
|
+
language: auto # auto-detect | typescript | javascript | python | go | rust
|
|
204
|
+
framework: auto # auto-detect | jest | vitest | pytest | go-test
|
|
205
|
+
outputDir: __tests__ # output directory for generated tests
|
|
206
|
+
|
|
207
|
+
coverage:
|
|
208
|
+
target: 90 # target coverage percentage
|
|
209
|
+
strict: false # fail if target not met
|
|
210
|
+
|
|
211
|
+
ai:
|
|
212
|
+
enabled: false # enable AI-powered generation
|
|
213
|
+
provider: openai # openai | anthropic | local | none
|
|
214
|
+
model: gpt-4o
|
|
215
|
+
apiKeyEnv: OPENAI_API_KEY
|
|
216
|
+
maxTokens: 4096
|
|
217
|
+
temperature: 0.2
|
|
218
|
+
privacyMode: true # never send raw source code
|
|
219
|
+
|
|
220
|
+
generation:
|
|
221
|
+
unitTests: true
|
|
222
|
+
integrationTests: true
|
|
223
|
+
edgeCaseTests: true
|
|
224
|
+
mockGeneration: true
|
|
225
|
+
mutationTesting: false
|
|
226
|
+
maxTestsPerFunction: 10
|
|
227
|
+
includeComments: true
|
|
228
|
+
|
|
229
|
+
incremental:
|
|
230
|
+
enabled: false
|
|
231
|
+
gitBased: true
|
|
232
|
+
cacheDir: .ai-testgen-cache
|
|
233
|
+
|
|
234
|
+
watch:
|
|
235
|
+
enabled: false
|
|
236
|
+
ignorePatterns:
|
|
237
|
+
- node_modules
|
|
238
|
+
- dist
|
|
239
|
+
- .git
|
|
240
|
+
- coverage
|
|
241
|
+
debounceMs: 300
|
|
242
|
+
|
|
243
|
+
exclude:
|
|
244
|
+
- node_modules/**
|
|
245
|
+
- dist/**
|
|
246
|
+
- coverage/**
|
|
247
|
+
- "**/*.d.ts"
|
|
248
|
+
|
|
249
|
+
include:
|
|
250
|
+
- src/**/*.{ts,tsx,js,jsx}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## CLI Reference
|
|
254
|
+
|
|
255
|
+
| Command | Description |
|
|
256
|
+
|---------|-------------|
|
|
257
|
+
| `ai-testgen generate <source>` | Generate test suites for source files |
|
|
258
|
+
| `ai-testgen init` | Create a sample `.aitestgen.yml` config |
|
|
259
|
+
| `ai-testgen watch <source>` | Watch mode — auto-generate on file changes |
|
|
260
|
+
| `ai-testgen mutation <source>` | Run mutation testing on a source file |
|
|
261
|
+
| `ai-testgen analyze <source>` | Analyze source code structure |
|
|
262
|
+
|
|
263
|
+
### Generate Options
|
|
264
|
+
|
|
265
|
+
| Flag | Description |
|
|
266
|
+
|------|-------------|
|
|
267
|
+
| `-o, --output <dir>` | Output directory for test files |
|
|
268
|
+
| `-c, --config <path>` | Path to config file |
|
|
269
|
+
| `-l, --language <lang>` | Force language detection |
|
|
270
|
+
| `-f, --framework <fw>` | Force test framework |
|
|
271
|
+
| `--no-ai` | Disable AI generation (AST only) |
|
|
272
|
+
| `--dry-run` | Preview without writing files |
|
|
273
|
+
| `--coverage` | Show coverage prediction |
|
|
274
|
+
| `--mutation` | Run mutation testing |
|
|
275
|
+
| `-v, --verbose` | Verbose output |
|
|
276
|
+
|
|
277
|
+
## How It Works
|
|
278
|
+
|
|
279
|
+
```
|
|
280
|
+
Source Code
|
|
281
|
+
|
|
|
282
|
+
v
|
|
283
|
+
+------------------+
|
|
284
|
+
| Language Detection| .ts/.js/.py/.go -> auto-detect
|
|
285
|
+
+------------------+
|
|
286
|
+
|
|
|
287
|
+
v
|
|
288
|
+
+------------------+
|
|
289
|
+
| AST Analysis | ts-morph (JS/TS) or regex-based (Python/Go)
|
|
290
|
+
| - Functions | Extract: exports, params, types, complexity
|
|
291
|
+
| - Classes | Detect: side effects, throws, async
|
|
292
|
+
| - Interfaces |
|
|
293
|
+
+------------------+
|
|
294
|
+
|
|
|
295
|
+
v
|
|
296
|
+
+------------------+
|
|
297
|
+
| Edge Case Engine | Null, undefined, empty, NaN, boundary
|
|
298
|
+
| - Type analysis | Optional params, error paths
|
|
299
|
+
| - Boundary values |
|
|
300
|
+
+------------------+
|
|
301
|
+
|
|
|
302
|
+
v
|
|
303
|
+
+------------------+
|
|
304
|
+
| Test Generation | Framework-specific templates
|
|
305
|
+
| - Unit tests | Jest / Vitest / pytest / go test
|
|
306
|
+
| - Integration |
|
|
307
|
+
| - Mock setup |
|
|
308
|
+
+------------------+
|
|
309
|
+
|
|
|
310
|
+
v
|
|
311
|
+
+------------------+
|
|
312
|
+
| AI Enhancement | (Optional) Refine with OpenAI
|
|
313
|
+
| - Privacy mode | Only sends metadata, not source
|
|
314
|
+
+------------------+
|
|
315
|
+
|
|
|
316
|
+
v
|
|
317
|
+
Generated Test Suite (90%+ coverage estimate)
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Mutation Testing
|
|
321
|
+
|
|
322
|
+
AI-TestGen can create code mutants to verify your tests actually catch bugs:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
ai-testgen mutation src/calculator.ts
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Mutation types:
|
|
329
|
+
- **Arithmetic**: `+` -> `-`, `*` -> `/`
|
|
330
|
+
- **Comparison**: `===` -> `!==`, `>` -> `<=`
|
|
331
|
+
- **Logical**: `&&` -> `||`
|
|
332
|
+
- **Boolean**: `true` -> `false`
|
|
333
|
+
- **String**: `"hello"` -> `""`
|
|
334
|
+
|
|
335
|
+
## Architecture
|
|
336
|
+
|
|
337
|
+
```
|
|
338
|
+
ai-testgen/
|
|
339
|
+
src/
|
|
340
|
+
analyzers/ # Language-specific AST analysis
|
|
341
|
+
js-ts-analyzer.ts # TypeScript/JavaScript via ts-morph
|
|
342
|
+
python-analyzer.ts# Python regex-based analysis
|
|
343
|
+
go-analyzer.ts # Go regex-based analysis
|
|
344
|
+
analyzer.ts # Unified interface + edge cases + mocks
|
|
345
|
+
generators/ # Test code generation
|
|
346
|
+
js-ts-generator.ts# Jest/Vitest test generation
|
|
347
|
+
python-generator.ts# pytest test generation
|
|
348
|
+
go-generator.ts # go test generation
|
|
349
|
+
ai-generator.ts # OpenAI-powered generation
|
|
350
|
+
mutation/ # Mutation testing
|
|
351
|
+
mutator.ts # Mutant generation and scoring
|
|
352
|
+
watcher/ # File watching
|
|
353
|
+
watcher.ts # fs.watch wrapper with debounce
|
|
354
|
+
config/ # Configuration management
|
|
355
|
+
defaults.ts # Default config values
|
|
356
|
+
loader.ts # YAML/JSON config loader
|
|
357
|
+
utils/ # Shared utilities
|
|
358
|
+
language.ts # Language/framework detection
|
|
359
|
+
logger.ts # Colored console output
|
|
360
|
+
file.ts # File I/O helpers
|
|
361
|
+
types.ts # TypeScript type definitions
|
|
362
|
+
coverage.ts # Coverage prediction
|
|
363
|
+
incremental.ts # Incremental mode cache
|
|
364
|
+
cli.ts # CLI entry point
|
|
365
|
+
index.ts # Public API exports
|
|
366
|
+
tests/ # Vitest test suite
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Tech Stack
|
|
370
|
+
|
|
371
|
+
- **TypeScript** — Strict mode, comprehensive types
|
|
372
|
+
- **ts-morph** — AST parsing for TypeScript/JavaScript
|
|
373
|
+
- **commander** — CLI framework
|
|
374
|
+
- **chalk** — Terminal colors
|
|
375
|
+
- **ora** — Loading spinners
|
|
376
|
+
- **js-yaml** — YAML config parsing
|
|
377
|
+
- **openai** — Optional AI enhancement
|
|
378
|
+
- **fast-glob** — File pattern matching
|
|
379
|
+
- **vitest** — Test framework
|
|
380
|
+
|
|
381
|
+
## License
|
|
382
|
+
|
|
383
|
+
MIT
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SourceAnalysis, SupportedLanguage, AnalyzedFunction, TestCase, MockDefinition } from '../types.js';
|
|
2
|
+
export declare function analyzeSource(filePath: string, language: SupportedLanguage): SourceAnalysis;
|
|
3
|
+
export declare function detectEdgeCases(fn: AnalyzedFunction): TestCase[];
|
|
4
|
+
export declare function detectMocks(analysis: SourceAnalysis): MockDefinition[];
|
|
5
|
+
export interface DependencyGraph {
|
|
6
|
+
files: Map<string, string[]>;
|
|
7
|
+
reverse: Map<string, string[]>;
|
|
8
|
+
}
|
|
9
|
+
export declare function buildDependencyGraph(analyses: SourceAnalysis[]): DependencyGraph;
|
|
10
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,EACR,cAAc,EACf,MAAM,aAAa,CAAC;AAKrB,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,cAAc,CAc3F;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,gBAAgB,GAAG,QAAQ,EAAE,CA6EhE;AAoBD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,cAAc,EAAE,CA8BtE;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAChC;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,eAAe,CAkBhF"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.analyzeSource = analyzeSource;
|
|
4
|
+
exports.detectEdgeCases = detectEdgeCases;
|
|
5
|
+
exports.detectMocks = detectMocks;
|
|
6
|
+
exports.buildDependencyGraph = buildDependencyGraph;
|
|
7
|
+
const js_ts_analyzer_js_1 = require("./js-ts-analyzer.js");
|
|
8
|
+
const python_analyzer_js_1 = require("./python-analyzer.js");
|
|
9
|
+
const go_analyzer_js_1 = require("./go-analyzer.js");
|
|
10
|
+
function analyzeSource(filePath, language) {
|
|
11
|
+
switch (language) {
|
|
12
|
+
case 'typescript':
|
|
13
|
+
case 'javascript':
|
|
14
|
+
return (0, js_ts_analyzer_js_1.analyzeTsSource)(filePath, language);
|
|
15
|
+
case 'python':
|
|
16
|
+
return (0, python_analyzer_js_1.analyzePythonSource)(filePath);
|
|
17
|
+
case 'go':
|
|
18
|
+
return (0, go_analyzer_js_1.analyzeGoSource)(filePath);
|
|
19
|
+
case 'rust':
|
|
20
|
+
throw new Error('Rust analysis is not yet supported. Use AI mode for Rust files.');
|
|
21
|
+
default:
|
|
22
|
+
throw new Error(`Unsupported language: ${language}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function detectEdgeCases(fn) {
|
|
26
|
+
const cases = [];
|
|
27
|
+
for (const param of fn.params) {
|
|
28
|
+
if (param.optional) {
|
|
29
|
+
cases.push({
|
|
30
|
+
name: `${fn.name} handles undefined ${param.name}`,
|
|
31
|
+
type: 'edge-case',
|
|
32
|
+
description: `Test that ${fn.name} gracefully handles undefined ${param.name}`,
|
|
33
|
+
code: '',
|
|
34
|
+
expectedBehavior: 'Should handle undefined parameter without throwing',
|
|
35
|
+
inputDescription: `${param.name} is undefined`,
|
|
36
|
+
tags: ['edge-case', 'undefined', param.name],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (param.type && (param.type.includes('string') || param.type.includes('String'))) {
|
|
40
|
+
cases.push(createEdgeCase(fn.name, param.name, 'empty string', '""', 'Should handle empty string input'), createEdgeCase(fn.name, param.name, 'very long string', '"a".repeat(10000)', 'Should handle very long string'), createEdgeCase(fn.name, param.name, 'string with special characters', '"\\n\\t\\0\\r"', 'Should handle special characters'));
|
|
41
|
+
}
|
|
42
|
+
if (param.type && (param.type.includes('number') || param.type.includes('Number'))) {
|
|
43
|
+
cases.push(createEdgeCase(fn.name, param.name, 'zero', '0', 'Should handle zero value'), createEdgeCase(fn.name, param.name, 'negative number', '-1', 'Should handle negative numbers'), createEdgeCase(fn.name, param.name, 'very large number', 'Number.MAX_SAFE_INTEGER', 'Should handle large numbers'), createEdgeCase(fn.name, param.name, 'NaN', 'NaN', 'Should handle NaN'), createEdgeCase(fn.name, param.name, 'Infinity', 'Infinity', 'Should handle Infinity'));
|
|
44
|
+
}
|
|
45
|
+
if (param.type && (param.type.includes('Array') || param.type.includes('[]'))) {
|
|
46
|
+
cases.push(createEdgeCase(fn.name, param.name, 'empty array', '[]', 'Should handle empty array'), createEdgeCase(fn.name, param.name, 'array with single element', '[item]', 'Should handle single-element array'), createEdgeCase(fn.name, param.name, 'very large array', 'Array(10000).fill(item)', 'Should handle large arrays'));
|
|
47
|
+
}
|
|
48
|
+
if (param.type && (param.type.includes('object') || param.type.includes('Object') || param.type.includes('{'))) {
|
|
49
|
+
cases.push(createEdgeCase(fn.name, param.name, 'empty object', '{}', 'Should handle empty object'), createEdgeCase(fn.name, param.name, 'null', 'null', 'Should handle null'));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (fn.throws.length > 0) {
|
|
53
|
+
for (const throws of fn.throws) {
|
|
54
|
+
cases.push({
|
|
55
|
+
name: `${fn.name} throws for invalid input`,
|
|
56
|
+
type: 'edge-case',
|
|
57
|
+
description: `Test that ${fn.name} throws when given invalid input`,
|
|
58
|
+
code: '',
|
|
59
|
+
expectedBehavior: `Should throw ${throws}`,
|
|
60
|
+
inputDescription: 'Invalid input that triggers error',
|
|
61
|
+
tags: ['edge-case', 'error-path'],
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (fn.isAsync) {
|
|
66
|
+
cases.push({
|
|
67
|
+
name: `${fn.name} handles rejection`,
|
|
68
|
+
type: 'edge-case',
|
|
69
|
+
description: `Test that ${fn.name} properly handles promise rejection`,
|
|
70
|
+
code: '',
|
|
71
|
+
expectedBehavior: 'Should handle promise rejection gracefully',
|
|
72
|
+
inputDescription: 'Input that causes promise rejection',
|
|
73
|
+
tags: ['edge-case', 'async'],
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return cases;
|
|
77
|
+
}
|
|
78
|
+
function createEdgeCase(fnName, paramName, caseName, value, expected) {
|
|
79
|
+
return {
|
|
80
|
+
name: `${fnName} handles ${caseName} for ${paramName}`,
|
|
81
|
+
type: 'edge-case',
|
|
82
|
+
description: `Test ${fnName} with ${caseName} for parameter ${paramName}`,
|
|
83
|
+
code: '',
|
|
84
|
+
expectedBehavior: expected,
|
|
85
|
+
inputDescription: `${paramName} = ${value}`,
|
|
86
|
+
tags: ['edge-case', caseName.replace(/\s+/g, '-')],
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function detectMocks(analysis) {
|
|
90
|
+
const mocks = [];
|
|
91
|
+
for (const imp of analysis.imports) {
|
|
92
|
+
if (imp.isTypeOnly)
|
|
93
|
+
continue;
|
|
94
|
+
if (!imp.modulePath.startsWith('.') && imp.namedImports.length > 0) {
|
|
95
|
+
for (const named of imp.namedImports) {
|
|
96
|
+
const isLikelyDependency = !imp.modulePath.startsWith('node:') &&
|
|
97
|
+
!['path', 'fs', 'os', 'util', 'events', 'stream', 'http', 'https', 'crypto'].includes(imp.modulePath);
|
|
98
|
+
if (isLikelyDependency) {
|
|
99
|
+
mocks.push({
|
|
100
|
+
moduleName: imp.modulePath,
|
|
101
|
+
mockName: `mock${named.charAt(0).toUpperCase() + named.slice(1)}`,
|
|
102
|
+
setup: `jest.mock('${imp.modulePath}');`,
|
|
103
|
+
teardown: null,
|
|
104
|
+
implementations: {
|
|
105
|
+
[named]: `jest.fn()`,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return mocks;
|
|
113
|
+
}
|
|
114
|
+
function buildDependencyGraph(analyses) {
|
|
115
|
+
const files = new Map();
|
|
116
|
+
const reverse = new Map();
|
|
117
|
+
for (const analysis of analyses) {
|
|
118
|
+
const deps = [];
|
|
119
|
+
for (const dep of analysis.dependencies) {
|
|
120
|
+
if (dep.startsWith('.')) {
|
|
121
|
+
deps.push(dep);
|
|
122
|
+
const rev = reverse.get(dep) ?? [];
|
|
123
|
+
rev.push(analysis.filePath);
|
|
124
|
+
reverse.set(dep, rev);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
files.set(analysis.filePath, deps);
|
|
128
|
+
}
|
|
129
|
+
return { files, reverse };
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/analyzers/analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzers/go-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EAMf,MAAM,aAAa,CAAC;AAErB,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAgBhE"}
|