ai-unit-test-generator 1.4.0 → 1.4.2
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/bin/cli.js +25 -3
- package/lib/core/scanner.mjs +6 -1
- package/lib/core/scorer.mjs +19 -1
- package/package.json +1 -2
- package/templates/default.config.json +4 -0
package/bin/cli.js
CHANGED
@@ -24,13 +24,16 @@ program
|
|
24
24
|
program
|
25
25
|
.command('scan')
|
26
26
|
.description('Scan code and generate priority scoring report')
|
27
|
-
.option('-c, --config <path>', 'Config file path', '
|
27
|
+
.option('-c, --config <path>', 'Config file path', 'ai-test.config.jsonc')
|
28
28
|
.option('-o, --output <dir>', 'Output directory', 'reports')
|
29
29
|
.option('--skip-git', 'Skip Git signals generation')
|
30
30
|
.action(async (options) => {
|
31
|
-
|
31
|
+
let { config, output, skipGit } = options
|
32
32
|
|
33
|
-
//
|
33
|
+
// 自动探测现有配置 & 初始化(不存在则创建)
|
34
|
+
const detectOrder = [config, 'ai-test.config.json', 'ai-test.config.jsonc']
|
35
|
+
const detected = detectOrder.find(p => existsSync(p))
|
36
|
+
if (detected) config = detected
|
34
37
|
if (!existsSync(config)) {
|
35
38
|
console.log('⚙️ Config not found, creating default config...')
|
36
39
|
const templatePath = join(PKG_ROOT, 'templates', 'default.config.json')
|
@@ -43,6 +46,25 @@ program
|
|
43
46
|
mkdirSync(output, { recursive: true })
|
44
47
|
}
|
45
48
|
|
49
|
+
// 可选:在扫描前自动运行覆盖率(由配置控制)
|
50
|
+
try {
|
51
|
+
const cfgText = existsSync(config) ? readFileSync(config, 'utf-8') : '{}'
|
52
|
+
const cfg = JSON.parse(cfgText)
|
53
|
+
const covCfg = cfg?.coverage || { runBeforeScan: false }
|
54
|
+
if (covCfg.runBeforeScan) {
|
55
|
+
console.log('🧪 Running coverage before scan...')
|
56
|
+
await new Promise((resolve, reject) => {
|
57
|
+
const cmd = covCfg.command || 'npx jest --coverage --silent'
|
58
|
+
const child = spawn(cmd, { stdio: 'inherit', shell: true, cwd: process.cwd() })
|
59
|
+
child.on('close', code => code === 0 ? resolve(0) : reject(new Error(`coverage exited ${code}`)))
|
60
|
+
child.on('error', reject)
|
61
|
+
})
|
62
|
+
}
|
63
|
+
} catch (err) {
|
64
|
+
console.warn('⚠️ Coverage step failed or Jest not installed. Skipping coverage and continuing scan.')
|
65
|
+
console.warn(' - npm i -D jest@29 ts-jest@29 @types/jest@29 jest-environment-jsdom@29 --legacy-peer-deps')
|
66
|
+
}
|
67
|
+
|
46
68
|
console.log('🚀 Starting code scan...\n')
|
47
69
|
|
48
70
|
try {
|
package/lib/core/scanner.mjs
CHANGED
@@ -22,7 +22,12 @@ function parseArgs(argv) {
|
|
22
22
|
return args
|
23
23
|
}
|
24
24
|
|
25
|
-
function
|
25
|
+
function stripJsonComments(s) {
|
26
|
+
return String(s)
|
27
|
+
.replace(/\/\*[\s\S]*?\*\//g, '') // block comments
|
28
|
+
.replace(/(^|\s)\/\/.*$/gm, '') // line comments
|
29
|
+
}
|
30
|
+
function loadJson(p) { try { return JSON.parse(stripJsonComments(readFileSync(p, 'utf8'))) } catch { return null } }
|
26
31
|
|
27
32
|
async function listFiles(excludeDirs = []) {
|
28
33
|
const fg = (await req('fast-glob', 'fast-glob')).default
|
package/lib/core/scorer.mjs
CHANGED
@@ -25,7 +25,25 @@ function loadJson(p) {
|
|
25
25
|
function toFixedDown(num, digits = 2) { const m = Math.pow(10, digits); return Math.floor(num * m) / m }
|
26
26
|
function clamp(n, min, max) { return Math.max(min, Math.min(max, n)) }
|
27
27
|
|
28
|
-
function
|
28
|
+
function stripJsonComments(s) {
|
29
|
+
return String(s)
|
30
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
31
|
+
.replace(/(^|\s)\/\/.*$/gm, '')
|
32
|
+
}
|
33
|
+
function loadConfig(pathFromArg) {
|
34
|
+
const fs = require('fs')
|
35
|
+
const paths = [pathFromArg, 'ai-test.config.jsonc', 'ai-test.config.json']
|
36
|
+
for (const p of paths) {
|
37
|
+
if (!p) continue
|
38
|
+
try {
|
39
|
+
if (fs.existsSync(p)) {
|
40
|
+
const raw = fs.readFileSync(p, 'utf8')
|
41
|
+
return JSON.parse(stripJsonComments(raw))
|
42
|
+
}
|
43
|
+
} catch {}
|
44
|
+
}
|
45
|
+
return {}
|
46
|
+
}
|
29
47
|
function pickWeight(cfg, key, def) { return cfg?.weights?.[key] ?? def }
|
30
48
|
function pickThreshold(cfg, key, def) { return cfg?.thresholds?.[key] ?? def }
|
31
49
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "ai-unit-test-generator",
|
3
|
-
"version": "1.4.
|
3
|
+
"version": "1.4.2",
|
4
4
|
"description": "AI-powered unit test generator with smart priority scoring",
|
5
5
|
"keywords": [
|
6
6
|
"unit-test",
|
@@ -66,4 +66,3 @@
|
|
66
66
|
},
|
67
67
|
"homepage": "https://github.com/YuhengZhou/ai-unit-test-generator#readme"
|
68
68
|
}
|
69
|
-
|