codeguard-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 +22 -0
- package/README.md +300 -0
- package/bin/testgen.js +17 -0
- package/dist/codebaseIndexer.d.ts +102 -0
- package/dist/codebaseIndexer.d.ts.map +1 -0
- package/dist/codebaseIndexer.js +291 -0
- package/dist/codebaseIndexer.js.map +1 -0
- package/dist/config.d.ts +35 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +104 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2720 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Codebase Indexer - Caches AST analysis for faster test generation
|
|
4
|
+
*
|
|
5
|
+
* This is completely optional. Test generation works fine without it,
|
|
6
|
+
* but indexing provides significant speed improvements.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.CodebaseIndexer = void 0;
|
|
10
|
+
const fs = require("fs");
|
|
11
|
+
const fsPromises = require("fs/promises");
|
|
12
|
+
const path = require("path");
|
|
13
|
+
const crypto = require("crypto");
|
|
14
|
+
class CodebaseIndexer {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.indexPath = '.codeguard-cache';
|
|
17
|
+
this.indexFile = '.codeguard-cache/index.json';
|
|
18
|
+
this.index = null;
|
|
19
|
+
this.version = '1.0.0';
|
|
20
|
+
// Ensure cache directory exists
|
|
21
|
+
if (!fs.existsSync(this.indexPath)) {
|
|
22
|
+
fs.mkdirSync(this.indexPath, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Check if index exists and is valid
|
|
27
|
+
*/
|
|
28
|
+
hasIndex() {
|
|
29
|
+
return fs.existsSync(this.indexFile);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Load index from disk
|
|
33
|
+
*/
|
|
34
|
+
async loadIndex() {
|
|
35
|
+
try {
|
|
36
|
+
if (!this.hasIndex()) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
const data = await fsPromises.readFile(this.indexFile, 'utf-8');
|
|
40
|
+
this.index = JSON.parse(data);
|
|
41
|
+
// Verify version
|
|
42
|
+
if (this.index.version !== this.version) {
|
|
43
|
+
console.log('â ď¸ Index version mismatch. Will rebuild.');
|
|
44
|
+
this.index = null;
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.log('â ď¸ Failed to load index. Will rebuild.');
|
|
51
|
+
this.index = null;
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Build complete index from scratch
|
|
57
|
+
*/
|
|
58
|
+
async buildIndex(rootDir, analyzeFileFn, progressCallback) {
|
|
59
|
+
console.log(`đ Scanning ${rootDir}...`);
|
|
60
|
+
// Get all source files
|
|
61
|
+
const files = await this.getAllSourceFiles(rootDir);
|
|
62
|
+
console.log(`đ Found ${files.length} files to index\n`);
|
|
63
|
+
// Initialize index
|
|
64
|
+
this.index = {
|
|
65
|
+
version: this.version,
|
|
66
|
+
createdAt: Date.now(),
|
|
67
|
+
lastUpdated: Date.now(),
|
|
68
|
+
files: {},
|
|
69
|
+
testMapping: {}
|
|
70
|
+
};
|
|
71
|
+
// Process each file
|
|
72
|
+
for (let i = 0; i < files.length; i++) {
|
|
73
|
+
const file = files[i];
|
|
74
|
+
if (progressCallback) {
|
|
75
|
+
progressCallback(i + 1, files.length, file);
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
// Get file metadata
|
|
79
|
+
const stats = fs.statSync(file);
|
|
80
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
81
|
+
const hash = this.calculateHash(content);
|
|
82
|
+
// Analyze file
|
|
83
|
+
const analysis = analyzeFileFn(file);
|
|
84
|
+
if (analysis.success) {
|
|
85
|
+
this.index.files[file] = {
|
|
86
|
+
metadata: {
|
|
87
|
+
path: file,
|
|
88
|
+
hash,
|
|
89
|
+
lastModified: stats.mtimeMs,
|
|
90
|
+
size: stats.size
|
|
91
|
+
},
|
|
92
|
+
analysis: analysis.analysis
|
|
93
|
+
};
|
|
94
|
+
// Check for corresponding test file
|
|
95
|
+
const testFile = this.findTestFile(file);
|
|
96
|
+
if (testFile) {
|
|
97
|
+
this.index.testMapping[file] = testFile;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.log(` â ď¸ Skipped ${file}: ${error.message}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Save index
|
|
106
|
+
await this.saveIndex();
|
|
107
|
+
console.log(`\nâ
Index built successfully!`);
|
|
108
|
+
console.log(` Indexed ${Object.keys(this.index.files).length} files`);
|
|
109
|
+
console.log(` Cache saved to ${this.indexPath}/\n`);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Update index for changed files only
|
|
113
|
+
*/
|
|
114
|
+
async updateIndex(changedFiles, analyzeFileFn) {
|
|
115
|
+
if (!this.index) {
|
|
116
|
+
throw new Error('Index not loaded. Call loadIndex() first.');
|
|
117
|
+
}
|
|
118
|
+
console.log(`đ Updating ${changedFiles.length} changed files...`);
|
|
119
|
+
for (const file of changedFiles) {
|
|
120
|
+
try {
|
|
121
|
+
const stats = fs.statSync(file);
|
|
122
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
123
|
+
const hash = this.calculateHash(content);
|
|
124
|
+
// Re-analyze file
|
|
125
|
+
const analysis = analyzeFileFn(file);
|
|
126
|
+
if (analysis.success) {
|
|
127
|
+
this.index.files[file] = {
|
|
128
|
+
metadata: {
|
|
129
|
+
path: file,
|
|
130
|
+
hash,
|
|
131
|
+
lastModified: stats.mtimeMs,
|
|
132
|
+
size: stats.size
|
|
133
|
+
},
|
|
134
|
+
analysis: analysis.analysis
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
console.log(` â ď¸ Failed to update ${file}: ${error.message}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
this.index.lastUpdated = Date.now();
|
|
143
|
+
await this.saveIndex();
|
|
144
|
+
console.log('â
Index updated!\n');
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Save index to disk
|
|
148
|
+
*/
|
|
149
|
+
async saveIndex() {
|
|
150
|
+
if (!this.index) {
|
|
151
|
+
throw new Error('No index to save');
|
|
152
|
+
}
|
|
153
|
+
await fsPromises.writeFile(this.indexFile, JSON.stringify(this.index, null, 2), 'utf-8');
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get cached file analysis
|
|
157
|
+
*/
|
|
158
|
+
getFileAnalysis(filePath) {
|
|
159
|
+
if (!this.index || !this.index.files[filePath]) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
return this.index.files[filePath].analysis;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Check if file needs re-indexing
|
|
166
|
+
*/
|
|
167
|
+
isFileStale(filePath) {
|
|
168
|
+
if (!this.index || !this.index.files[filePath]) {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const stats = fs.statSync(filePath);
|
|
173
|
+
const cached = this.index.files[filePath].metadata;
|
|
174
|
+
// Check if file was modified
|
|
175
|
+
return stats.mtimeMs > cached.lastModified;
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Get files that need re-indexing
|
|
183
|
+
*/
|
|
184
|
+
getStaleFiles() {
|
|
185
|
+
if (!this.index) {
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
const staleFiles = [];
|
|
189
|
+
for (const filePath in this.index.files) {
|
|
190
|
+
if (this.isFileStale(filePath)) {
|
|
191
|
+
staleFiles.push(filePath);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return staleFiles;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Get index statistics
|
|
198
|
+
*/
|
|
199
|
+
getStats() {
|
|
200
|
+
if (!this.index) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
const fileCount = Object.keys(this.index.files).length;
|
|
204
|
+
const functionCount = Object.values(this.index.files).reduce((sum, f) => sum + f.analysis.functions.length, 0);
|
|
205
|
+
const testCount = Object.values(this.index.testMapping).filter(t => t !== null).length;
|
|
206
|
+
return {
|
|
207
|
+
version: this.index.version,
|
|
208
|
+
fileCount,
|
|
209
|
+
functionCount,
|
|
210
|
+
testCount,
|
|
211
|
+
createdAt: new Date(this.index.createdAt).toLocaleString(),
|
|
212
|
+
lastUpdated: new Date(this.index.lastUpdated).toLocaleString()
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Clear index cache
|
|
217
|
+
*/
|
|
218
|
+
async clearCache() {
|
|
219
|
+
if (fs.existsSync(this.indexFile)) {
|
|
220
|
+
await fsPromises.unlink(this.indexFile);
|
|
221
|
+
}
|
|
222
|
+
this.index = null;
|
|
223
|
+
console.log('â
Cache cleared');
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get all source files recursively
|
|
227
|
+
*/
|
|
228
|
+
async getAllSourceFiles(dir, fileList = []) {
|
|
229
|
+
const excludeDirs = ['node_modules', 'dist', 'build', '.git', 'coverage', '__tests__', 'tests'];
|
|
230
|
+
const extensions = ['.ts', '.tsx', '.js', '.jsx'];
|
|
231
|
+
const items = await fsPromises.readdir(dir);
|
|
232
|
+
for (const item of items) {
|
|
233
|
+
const fullPath = path.join(dir, item);
|
|
234
|
+
const stat = await fsPromises.stat(fullPath);
|
|
235
|
+
if (stat.isDirectory() && !excludeDirs.includes(item)) {
|
|
236
|
+
await this.getAllSourceFiles(fullPath, fileList);
|
|
237
|
+
}
|
|
238
|
+
else if (stat.isFile()) {
|
|
239
|
+
const ext = path.extname(item);
|
|
240
|
+
if (extensions.includes(ext) &&
|
|
241
|
+
!item.endsWith('.test.ts') &&
|
|
242
|
+
!item.endsWith('.spec.ts') &&
|
|
243
|
+
!item.endsWith('.test.js') &&
|
|
244
|
+
!item.endsWith('.spec.js')) {
|
|
245
|
+
fileList.push(fullPath);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return fileList;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Find corresponding test file for a source file
|
|
253
|
+
*/
|
|
254
|
+
findTestFile(sourceFile) {
|
|
255
|
+
const testDirs = ['tests', '__tests__', 'test', '__test__'];
|
|
256
|
+
const baseName = path.basename(sourceFile).replace(/\.(ts|js)x?$/, '');
|
|
257
|
+
const sourceDir = path.dirname(sourceFile);
|
|
258
|
+
// Try common test file patterns
|
|
259
|
+
const patterns = [
|
|
260
|
+
`${baseName}.test.ts`,
|
|
261
|
+
`${baseName}.spec.ts`,
|
|
262
|
+
`${baseName}.test.js`,
|
|
263
|
+
`${baseName}.spec.js`
|
|
264
|
+
];
|
|
265
|
+
// Check in same directory
|
|
266
|
+
for (const pattern of patterns) {
|
|
267
|
+
const testPath = path.join(sourceDir, pattern);
|
|
268
|
+
if (fs.existsSync(testPath)) {
|
|
269
|
+
return testPath;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// Check in test directories
|
|
273
|
+
for (const testDir of testDirs) {
|
|
274
|
+
for (const pattern of patterns) {
|
|
275
|
+
const testPath = path.join(testDir, pattern);
|
|
276
|
+
if (fs.existsSync(testPath)) {
|
|
277
|
+
return testPath;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Calculate file hash
|
|
285
|
+
*/
|
|
286
|
+
calculateHash(content) {
|
|
287
|
+
return crypto.createHash('md5').update(content).digest('hex');
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
exports.CodebaseIndexer = CodebaseIndexer;
|
|
291
|
+
//# sourceMappingURL=codebaseIndexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codebaseIndexer.js","sourceRoot":"","sources":["../src/codebaseIndexer.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface CodeGuardConfig {
|
|
2
|
+
aiProvider: 'openai' | 'gemini' | 'claude';
|
|
3
|
+
apiKeys: {
|
|
4
|
+
claude?: string;
|
|
5
|
+
openai?: string;
|
|
6
|
+
gemini?: string;
|
|
7
|
+
};
|
|
8
|
+
models?: {
|
|
9
|
+
claude?: string;
|
|
10
|
+
openai?: string;
|
|
11
|
+
gemini?: string;
|
|
12
|
+
};
|
|
13
|
+
testDir?: string;
|
|
14
|
+
extensions?: string[];
|
|
15
|
+
excludeDirs?: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface Config {
|
|
18
|
+
extensions: string[];
|
|
19
|
+
excludeDirs: string[];
|
|
20
|
+
testDir: string;
|
|
21
|
+
aiProvider: 'openai' | 'gemini' | 'claude';
|
|
22
|
+
apiKeys: {
|
|
23
|
+
claude?: string;
|
|
24
|
+
openai?: string;
|
|
25
|
+
gemini?: string;
|
|
26
|
+
};
|
|
27
|
+
models: {
|
|
28
|
+
claude: string;
|
|
29
|
+
openai: string;
|
|
30
|
+
gemini: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export declare function loadConfig(): Config;
|
|
34
|
+
export declare function validateConfig(config: Config): void;
|
|
35
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC3C,OAAO,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,MAAM,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,MAAM;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC3C,OAAO,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAQD,wBAAgB,UAAU,IAAI,MAAM,CA4EnC;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAuBnD"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadConfig = loadConfig;
|
|
4
|
+
exports.validateConfig = validateConfig;
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const DEFAULT_MODELS = {
|
|
8
|
+
claude: 'claude-sonnet-4-5-20250929',
|
|
9
|
+
openai: 'gpt-5-mini',
|
|
10
|
+
gemini: 'gemini-2.0-flash-lite'
|
|
11
|
+
};
|
|
12
|
+
function loadConfig() {
|
|
13
|
+
const configPath = path.join(process.cwd(), 'codeguard.json');
|
|
14
|
+
// Check if config file exists
|
|
15
|
+
if (!fs.existsSync(configPath)) {
|
|
16
|
+
// Fall back to environment variables for backward compatibility
|
|
17
|
+
console.log('â ď¸ codeguard.json not found. Using environment variables (deprecated).');
|
|
18
|
+
console.log(' Please create a codeguard.json file in your project root.');
|
|
19
|
+
console.log(' See: https://github.com/yourusername/codeguard-testgen for setup.\n');
|
|
20
|
+
return {
|
|
21
|
+
aiProvider: 'claude',
|
|
22
|
+
testDir: 'src/tests',
|
|
23
|
+
extensions: ['.ts', '.tsx', '.js', '.jsx'],
|
|
24
|
+
excludeDirs: ['node_modules', 'dist', 'build', '.git', 'coverage', '__tests__'],
|
|
25
|
+
apiKeys: {
|
|
26
|
+
claude: process.env.ANTHROPIC_API_KEY,
|
|
27
|
+
openai: process.env.OPENAI_API_KEY,
|
|
28
|
+
gemini: process.env.GEMINI_API_KEY
|
|
29
|
+
},
|
|
30
|
+
models: DEFAULT_MODELS
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// Load and parse config file
|
|
34
|
+
let config;
|
|
35
|
+
try {
|
|
36
|
+
const configContent = fs.readFileSync(configPath, 'utf-8');
|
|
37
|
+
config = JSON.parse(configContent);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
throw new Error(`Failed to parse codeguard.json: ${error.message}`);
|
|
41
|
+
}
|
|
42
|
+
// Validate required fields
|
|
43
|
+
if (!config.aiProvider) {
|
|
44
|
+
throw new Error('codeguard.json must specify "aiProvider" (claude, openai, or gemini)');
|
|
45
|
+
}
|
|
46
|
+
if (!['claude', 'openai', 'gemini'].includes(config.aiProvider)) {
|
|
47
|
+
throw new Error(`Invalid aiProvider "${config.aiProvider}". Must be: claude, openai, or gemini`);
|
|
48
|
+
}
|
|
49
|
+
if (!config.apiKeys || typeof config.apiKeys !== 'object') {
|
|
50
|
+
throw new Error('codeguard.json must include "apiKeys" object with API keys');
|
|
51
|
+
}
|
|
52
|
+
// Validate that the selected provider has an API key
|
|
53
|
+
const selectedProviderKey = config.apiKeys[config.aiProvider];
|
|
54
|
+
if (!selectedProviderKey) {
|
|
55
|
+
throw new Error(`API key for "${config.aiProvider}" not found in codeguard.json`);
|
|
56
|
+
}
|
|
57
|
+
// Build final config with defaults
|
|
58
|
+
return {
|
|
59
|
+
aiProvider: config.aiProvider,
|
|
60
|
+
testDir: config.testDir || 'src/tests',
|
|
61
|
+
extensions: config.extensions || ['.ts', '.tsx', '.js', '.jsx'],
|
|
62
|
+
excludeDirs: config.excludeDirs || [
|
|
63
|
+
'node_modules',
|
|
64
|
+
'dist',
|
|
65
|
+
'build',
|
|
66
|
+
'.git',
|
|
67
|
+
'coverage',
|
|
68
|
+
'__tests__',
|
|
69
|
+
'tests',
|
|
70
|
+
'test',
|
|
71
|
+
'.codeguard-cache',
|
|
72
|
+
'.testgen-cache'
|
|
73
|
+
],
|
|
74
|
+
apiKeys: config.apiKeys,
|
|
75
|
+
models: {
|
|
76
|
+
claude: config.models?.claude || DEFAULT_MODELS.claude,
|
|
77
|
+
openai: config.models?.openai || DEFAULT_MODELS.openai,
|
|
78
|
+
gemini: config.models?.gemini || DEFAULT_MODELS.gemini
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function validateConfig(config) {
|
|
83
|
+
// Validate API key for selected provider
|
|
84
|
+
const apiKey = config.apiKeys[config.aiProvider];
|
|
85
|
+
if (!apiKey) {
|
|
86
|
+
throw new Error(`No API key configured for ${config.aiProvider}`);
|
|
87
|
+
}
|
|
88
|
+
// Validate API key format (basic checks)
|
|
89
|
+
if (config.aiProvider === 'claude' && !apiKey.startsWith('sk-ant-')) {
|
|
90
|
+
console.warn('â ď¸ Claude API key should start with "sk-ant-"');
|
|
91
|
+
}
|
|
92
|
+
else if (config.aiProvider === 'openai' && !apiKey.startsWith('sk-')) {
|
|
93
|
+
console.warn('â ď¸ OpenAI API key should start with "sk-"');
|
|
94
|
+
}
|
|
95
|
+
// Validate test directory
|
|
96
|
+
if (!config.testDir || config.testDir.trim() === '') {
|
|
97
|
+
throw new Error('testDir cannot be empty');
|
|
98
|
+
}
|
|
99
|
+
// Validate extensions
|
|
100
|
+
if (!config.extensions || config.extensions.length === 0) {
|
|
101
|
+
throw new Error('extensions array cannot be empty');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/** //This version has lefitimate failure detection and reporting.
|
|
3
|
+
* AI-Powered Unit Test Generator with AST Analysis
|
|
4
|
+
* Supports OpenAI, Gemini, and Claude with function calling
|
|
5
|
+
*
|
|
6
|
+
* Usage: npx ts-node src/testgen.ts
|
|
7
|
+
*
|
|
8
|
+
* Required packages: npm install @babel/parser @babel/traverse ts-node
|
|
9
|
+
*
|
|
10
|
+
* Required environment variables:
|
|
11
|
+
* - OPENAI_API_KEY (for OpenAI)
|
|
12
|
+
* - GEMINI_API_KEY (for Gemini)
|
|
13
|
+
* - ANTHROPIC_API_KEY (for Claude)
|
|
14
|
+
*/
|
|
15
|
+
import { CodebaseIndexer } from './codebaseIndexer';
|
|
16
|
+
interface Tool {
|
|
17
|
+
name: string;
|
|
18
|
+
description: string;
|
|
19
|
+
input_schema: {
|
|
20
|
+
type: string;
|
|
21
|
+
properties: Record<string, any>;
|
|
22
|
+
required: string[];
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
declare const TOOLS: Tool[];
|
|
26
|
+
declare function analyzeFileAST(filePath: string): any;
|
|
27
|
+
declare function getFunctionAST(filePath: string, functionName: string): any;
|
|
28
|
+
declare function getImportsAST(filePath: string): any;
|
|
29
|
+
declare function getTypeDefinitions(filePath: string): any;
|
|
30
|
+
declare function getClassMethods(filePath: string, className: string): any;
|
|
31
|
+
declare function replaceFunctionTests(testFilePath: string, functionName: string, newTestContent: string): Promise<any>;
|
|
32
|
+
declare function deleteLines(filePath: string, startLine: number, endLine: number): Promise<any>;
|
|
33
|
+
declare function insertLines(filePath: string, lineNumber: number, content: string): Promise<any>;
|
|
34
|
+
declare function replaceLines(filePath: string, startLine: number, endLine: number, newContent: string): Promise<any>;
|
|
35
|
+
declare function executeTool(toolName: string, args: any): Promise<any>;
|
|
36
|
+
declare function generateTests(sourceFile: string): Promise<string>;
|
|
37
|
+
declare function generateTestsForFolder(): Promise<void>;
|
|
38
|
+
declare function generateTestsForFunctions(sourceFile: string, functionNames: string[]): Promise<string>;
|
|
39
|
+
declare function generateTestsForFunction(): Promise<void>;
|
|
40
|
+
declare function main(): Promise<void>;
|
|
41
|
+
export { main, generateTests, generateTestsForFolder, generateTestsForFunction, generateTestsForFunctions, executeTool, analyzeFileAST, getFunctionAST, getImportsAST, getTypeDefinitions, getClassMethods, replaceFunctionTests, deleteLines, insertLines, replaceLines, CodebaseIndexer, TOOLS };
|
|
42
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG;AAaH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AA6BpD,UAAU,IAAI;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH;AAmED,QAAA,MAAM,KAAK,EAAE,IAAI,EA8UhB,CAAC;AA2BF,iBAAS,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CA4J7C;AAqDD,iBAAS,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,GAAG,CAyCnE;AAyBD,iBAAS,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CA0D5C;AAED,iBAAS,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAuEjD;AAED,iBAAS,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,GAAG,CAoDjE;AAiLD,iBAAe,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA0DpH;AA+JD,iBAAe,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAkC7F;AAED,iBAAe,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA2B9F;AAED,iBAAe,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAkClH;AAyBD,iBAAe,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAwHpE;AA4QD,iBAAe,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsehE;AAmCD,iBAAe,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CA2DrD;AAGD,iBAAe,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA0WrG;AAED,iBAAe,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC,CA8DvD;AAED,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAyJnC;AAQD,OAAO,EACL,IAAI,EACJ,aAAa,EACb,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,WAAW,EACX,cAAc,EACd,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,eAAe,EACf,KAAK,EACN,CAAC"}
|