qat-cli 0.3.2 → 0.3.3
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/README.md +1 -1
- package/dist/cli.js +85 -12
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +80 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +128 -120
- package/dist/index.d.ts +128 -120
- package/dist/index.js +80 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI 相关类型定义
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/** AI 能力标识 */
|
|
6
|
+
interface AICapability {
|
|
7
|
+
generateTest: boolean;
|
|
8
|
+
analyzeResult: boolean;
|
|
9
|
+
suggestFix: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** 源码分析摘要(传给 AI 的精简版) */
|
|
12
|
+
interface SourceAnalysisSummary {
|
|
13
|
+
/** 导出项摘要 */
|
|
14
|
+
exports: Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
kind: string;
|
|
17
|
+
params?: string[];
|
|
18
|
+
isAsync?: boolean;
|
|
19
|
+
}>;
|
|
20
|
+
/** Vue Props */
|
|
21
|
+
props?: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
type: string;
|
|
24
|
+
required: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
/** Vue Emits */
|
|
27
|
+
emits?: Array<{
|
|
28
|
+
name: string;
|
|
29
|
+
params?: string[];
|
|
30
|
+
}>;
|
|
31
|
+
/** Options API 方法 */
|
|
32
|
+
methods?: string[];
|
|
33
|
+
/** computed 属性 */
|
|
34
|
+
computed?: string[];
|
|
35
|
+
}
|
|
36
|
+
/** AI 生成测试请求 */
|
|
37
|
+
interface AIGenerateTestRequest {
|
|
38
|
+
type: TestType;
|
|
39
|
+
target: string;
|
|
40
|
+
context?: string;
|
|
41
|
+
framework?: 'vue';
|
|
42
|
+
/** 源码分析摘要 */
|
|
43
|
+
analysis?: SourceAnalysisSummary;
|
|
44
|
+
}
|
|
45
|
+
/** AI 生成测试响应 */
|
|
46
|
+
interface AIGenerateTestResponse {
|
|
47
|
+
code: string;
|
|
48
|
+
description: string;
|
|
49
|
+
confidence: number;
|
|
50
|
+
}
|
|
51
|
+
/** AI 分析结果请求 */
|
|
52
|
+
interface AIAnalyzeResultRequest {
|
|
53
|
+
testResults: TestRunResult[];
|
|
54
|
+
errorLogs?: string[];
|
|
55
|
+
screenshots?: string[];
|
|
56
|
+
}
|
|
57
|
+
/** AI 分析结果响应 */
|
|
58
|
+
interface AIAnalyzeResultResponse {
|
|
59
|
+
analysis: string;
|
|
60
|
+
suggestions: string[];
|
|
61
|
+
severity: 'info' | 'warning' | 'error';
|
|
62
|
+
}
|
|
63
|
+
/** AI 审计测试请求 */
|
|
64
|
+
interface AIReviewTestRequest {
|
|
65
|
+
/** 被测源码文件路径 */
|
|
66
|
+
target: string;
|
|
67
|
+
/** 被测源码内容 */
|
|
68
|
+
sourceCode: string;
|
|
69
|
+
/** 源码分析摘要 */
|
|
70
|
+
analysis?: SourceAnalysisSummary;
|
|
71
|
+
/** 生成的测试代码 */
|
|
72
|
+
testCode: string;
|
|
73
|
+
/** 测试类型 */
|
|
74
|
+
testType: TestType;
|
|
75
|
+
/** 生成者 AI 的描述/意图 */
|
|
76
|
+
generationDescription?: string;
|
|
77
|
+
}
|
|
78
|
+
/** AI 审计测试响应 */
|
|
79
|
+
interface AIReviewTestResponse {
|
|
80
|
+
/** 是否通过审计 */
|
|
81
|
+
approved: boolean;
|
|
82
|
+
/** 审计评分 0-1 */
|
|
83
|
+
score: number;
|
|
84
|
+
/** 审计意见 */
|
|
85
|
+
feedback: string;
|
|
86
|
+
/** 具体问题列表 */
|
|
87
|
+
issues: string[];
|
|
88
|
+
/** 改进建议 */
|
|
89
|
+
suggestions: string[];
|
|
90
|
+
}
|
|
91
|
+
/** AI Provider 接口 */
|
|
92
|
+
interface AIProvider {
|
|
93
|
+
readonly name: string;
|
|
94
|
+
readonly capabilities: AICapability;
|
|
95
|
+
generateTest(req: AIGenerateTestRequest): Promise<AIGenerateTestResponse>;
|
|
96
|
+
analyzeResult(req: AIAnalyzeResultRequest): Promise<AIAnalyzeResultResponse>;
|
|
97
|
+
suggestFix(error: TestError): Promise<string[]>;
|
|
98
|
+
reviewTest(req: AIReviewTestRequest): Promise<AIReviewTestResponse>;
|
|
99
|
+
}
|
|
100
|
+
/** AI 配置 */
|
|
101
|
+
interface AIConfig {
|
|
102
|
+
provider: string;
|
|
103
|
+
apiKey?: string;
|
|
104
|
+
model?: string;
|
|
105
|
+
baseUrl?: string;
|
|
106
|
+
}
|
|
107
|
+
/** 预置 Provider 配置(用于 init 向导) */
|
|
108
|
+
interface AIPresetProvider {
|
|
109
|
+
/** 标识名 */
|
|
110
|
+
id: string;
|
|
111
|
+
/** 显示名 */
|
|
112
|
+
name: string;
|
|
113
|
+
/** 默认 base URL */
|
|
114
|
+
baseUrl: string;
|
|
115
|
+
/** 默认模型 */
|
|
116
|
+
defaultModel: string;
|
|
117
|
+
/** 是否需要 API Key */
|
|
118
|
+
requiresApiKey: boolean;
|
|
119
|
+
}
|
|
120
|
+
|
|
1
121
|
/**
|
|
2
122
|
* QAT 全局类型定义
|
|
3
123
|
*/
|
|
@@ -161,126 +281,6 @@ interface SetupOptions extends GlobalOptions {
|
|
|
161
281
|
dryRun?: boolean;
|
|
162
282
|
}
|
|
163
283
|
|
|
164
|
-
/**
|
|
165
|
-
* AI 相关类型定义
|
|
166
|
-
*/
|
|
167
|
-
|
|
168
|
-
/** AI 能力标识 */
|
|
169
|
-
interface AICapability {
|
|
170
|
-
generateTest: boolean;
|
|
171
|
-
analyzeResult: boolean;
|
|
172
|
-
suggestFix: boolean;
|
|
173
|
-
}
|
|
174
|
-
/** 源码分析摘要(传给 AI 的精简版) */
|
|
175
|
-
interface SourceAnalysisSummary {
|
|
176
|
-
/** 导出项摘要 */
|
|
177
|
-
exports: Array<{
|
|
178
|
-
name: string;
|
|
179
|
-
kind: string;
|
|
180
|
-
params?: string[];
|
|
181
|
-
isAsync?: boolean;
|
|
182
|
-
}>;
|
|
183
|
-
/** Vue Props */
|
|
184
|
-
props?: Array<{
|
|
185
|
-
name: string;
|
|
186
|
-
type: string;
|
|
187
|
-
required: boolean;
|
|
188
|
-
}>;
|
|
189
|
-
/** Vue Emits */
|
|
190
|
-
emits?: Array<{
|
|
191
|
-
name: string;
|
|
192
|
-
params?: string[];
|
|
193
|
-
}>;
|
|
194
|
-
/** Options API 方法 */
|
|
195
|
-
methods?: string[];
|
|
196
|
-
/** computed 属性 */
|
|
197
|
-
computed?: string[];
|
|
198
|
-
}
|
|
199
|
-
/** AI 生成测试请求 */
|
|
200
|
-
interface AIGenerateTestRequest {
|
|
201
|
-
type: TestType;
|
|
202
|
-
target: string;
|
|
203
|
-
context?: string;
|
|
204
|
-
framework?: 'vue';
|
|
205
|
-
/** 源码分析摘要 */
|
|
206
|
-
analysis?: SourceAnalysisSummary;
|
|
207
|
-
}
|
|
208
|
-
/** AI 生成测试响应 */
|
|
209
|
-
interface AIGenerateTestResponse {
|
|
210
|
-
code: string;
|
|
211
|
-
description: string;
|
|
212
|
-
confidence: number;
|
|
213
|
-
}
|
|
214
|
-
/** AI 分析结果请求 */
|
|
215
|
-
interface AIAnalyzeResultRequest {
|
|
216
|
-
testResults: TestRunResult[];
|
|
217
|
-
errorLogs?: string[];
|
|
218
|
-
screenshots?: string[];
|
|
219
|
-
}
|
|
220
|
-
/** AI 分析结果响应 */
|
|
221
|
-
interface AIAnalyzeResultResponse {
|
|
222
|
-
analysis: string;
|
|
223
|
-
suggestions: string[];
|
|
224
|
-
severity: 'info' | 'warning' | 'error';
|
|
225
|
-
}
|
|
226
|
-
/** AI 审计测试请求 */
|
|
227
|
-
interface AIReviewTestRequest {
|
|
228
|
-
/** 被测源码文件路径 */
|
|
229
|
-
target: string;
|
|
230
|
-
/** 被测源码内容 */
|
|
231
|
-
sourceCode: string;
|
|
232
|
-
/** 源码分析摘要 */
|
|
233
|
-
analysis?: SourceAnalysisSummary;
|
|
234
|
-
/** 生成的测试代码 */
|
|
235
|
-
testCode: string;
|
|
236
|
-
/** 测试类型 */
|
|
237
|
-
testType: TestType;
|
|
238
|
-
/** 生成者 AI 的描述/意图 */
|
|
239
|
-
generationDescription?: string;
|
|
240
|
-
}
|
|
241
|
-
/** AI 审计测试响应 */
|
|
242
|
-
interface AIReviewTestResponse {
|
|
243
|
-
/** 是否通过审计 */
|
|
244
|
-
approved: boolean;
|
|
245
|
-
/** 审计评分 0-1 */
|
|
246
|
-
score: number;
|
|
247
|
-
/** 审计意见 */
|
|
248
|
-
feedback: string;
|
|
249
|
-
/** 具体问题列表 */
|
|
250
|
-
issues: string[];
|
|
251
|
-
/** 改进建议 */
|
|
252
|
-
suggestions: string[];
|
|
253
|
-
}
|
|
254
|
-
/** AI Provider 接口 */
|
|
255
|
-
interface AIProvider {
|
|
256
|
-
readonly name: string;
|
|
257
|
-
readonly capabilities: AICapability;
|
|
258
|
-
generateTest(req: AIGenerateTestRequest): Promise<AIGenerateTestResponse>;
|
|
259
|
-
analyzeResult(req: AIAnalyzeResultRequest): Promise<AIAnalyzeResultResponse>;
|
|
260
|
-
suggestFix(error: TestError): Promise<string[]>;
|
|
261
|
-
reviewTest(req: AIReviewTestRequest): Promise<AIReviewTestResponse>;
|
|
262
|
-
}
|
|
263
|
-
/** AI 配置 */
|
|
264
|
-
interface AIConfig {
|
|
265
|
-
provider: string;
|
|
266
|
-
apiKey?: string;
|
|
267
|
-
model?: string;
|
|
268
|
-
baseUrl?: string;
|
|
269
|
-
}
|
|
270
|
-
/** 预置 Provider 配置(用于 init 向导) */
|
|
271
|
-
interface AIPresetProvider {
|
|
272
|
-
/** 标识名 */
|
|
273
|
-
id: string;
|
|
274
|
-
/** 显示名 */
|
|
275
|
-
name: string;
|
|
276
|
-
/** 默认 base URL */
|
|
277
|
-
baseUrl: string;
|
|
278
|
-
/** 默认模型 */
|
|
279
|
-
defaultModel: string;
|
|
280
|
-
/** 是否需要 API Key */
|
|
281
|
-
requiresApiKey: boolean;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
284
|
/**
|
|
285
285
|
* 配置管理服务 - 读取/解析/校验/生成 qat.config.ts
|
|
286
286
|
*/
|
|
@@ -738,6 +738,14 @@ declare class OpenAICompatibleProvider implements AIProvider {
|
|
|
738
738
|
private chat;
|
|
739
739
|
private buildGenerateTestSystemPrompt;
|
|
740
740
|
private buildGenerateTestUserPrompt;
|
|
741
|
+
/**
|
|
742
|
+
* 根据测试类型和源文件路径,计算从测试文件到源文件的正确相对导入路径
|
|
743
|
+
*/
|
|
744
|
+
private computeTestImportPath;
|
|
745
|
+
/**
|
|
746
|
+
* 获取测试输出目录
|
|
747
|
+
*/
|
|
748
|
+
private getTestOutputDir;
|
|
741
749
|
private parseGenerateTestResponse;
|
|
742
750
|
private buildReviewTestSystemPrompt;
|
|
743
751
|
private buildReviewTestUserPrompt;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI 相关类型定义
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/** AI 能力标识 */
|
|
6
|
+
interface AICapability {
|
|
7
|
+
generateTest: boolean;
|
|
8
|
+
analyzeResult: boolean;
|
|
9
|
+
suggestFix: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** 源码分析摘要(传给 AI 的精简版) */
|
|
12
|
+
interface SourceAnalysisSummary {
|
|
13
|
+
/** 导出项摘要 */
|
|
14
|
+
exports: Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
kind: string;
|
|
17
|
+
params?: string[];
|
|
18
|
+
isAsync?: boolean;
|
|
19
|
+
}>;
|
|
20
|
+
/** Vue Props */
|
|
21
|
+
props?: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
type: string;
|
|
24
|
+
required: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
/** Vue Emits */
|
|
27
|
+
emits?: Array<{
|
|
28
|
+
name: string;
|
|
29
|
+
params?: string[];
|
|
30
|
+
}>;
|
|
31
|
+
/** Options API 方法 */
|
|
32
|
+
methods?: string[];
|
|
33
|
+
/** computed 属性 */
|
|
34
|
+
computed?: string[];
|
|
35
|
+
}
|
|
36
|
+
/** AI 生成测试请求 */
|
|
37
|
+
interface AIGenerateTestRequest {
|
|
38
|
+
type: TestType;
|
|
39
|
+
target: string;
|
|
40
|
+
context?: string;
|
|
41
|
+
framework?: 'vue';
|
|
42
|
+
/** 源码分析摘要 */
|
|
43
|
+
analysis?: SourceAnalysisSummary;
|
|
44
|
+
}
|
|
45
|
+
/** AI 生成测试响应 */
|
|
46
|
+
interface AIGenerateTestResponse {
|
|
47
|
+
code: string;
|
|
48
|
+
description: string;
|
|
49
|
+
confidence: number;
|
|
50
|
+
}
|
|
51
|
+
/** AI 分析结果请求 */
|
|
52
|
+
interface AIAnalyzeResultRequest {
|
|
53
|
+
testResults: TestRunResult[];
|
|
54
|
+
errorLogs?: string[];
|
|
55
|
+
screenshots?: string[];
|
|
56
|
+
}
|
|
57
|
+
/** AI 分析结果响应 */
|
|
58
|
+
interface AIAnalyzeResultResponse {
|
|
59
|
+
analysis: string;
|
|
60
|
+
suggestions: string[];
|
|
61
|
+
severity: 'info' | 'warning' | 'error';
|
|
62
|
+
}
|
|
63
|
+
/** AI 审计测试请求 */
|
|
64
|
+
interface AIReviewTestRequest {
|
|
65
|
+
/** 被测源码文件路径 */
|
|
66
|
+
target: string;
|
|
67
|
+
/** 被测源码内容 */
|
|
68
|
+
sourceCode: string;
|
|
69
|
+
/** 源码分析摘要 */
|
|
70
|
+
analysis?: SourceAnalysisSummary;
|
|
71
|
+
/** 生成的测试代码 */
|
|
72
|
+
testCode: string;
|
|
73
|
+
/** 测试类型 */
|
|
74
|
+
testType: TestType;
|
|
75
|
+
/** 生成者 AI 的描述/意图 */
|
|
76
|
+
generationDescription?: string;
|
|
77
|
+
}
|
|
78
|
+
/** AI 审计测试响应 */
|
|
79
|
+
interface AIReviewTestResponse {
|
|
80
|
+
/** 是否通过审计 */
|
|
81
|
+
approved: boolean;
|
|
82
|
+
/** 审计评分 0-1 */
|
|
83
|
+
score: number;
|
|
84
|
+
/** 审计意见 */
|
|
85
|
+
feedback: string;
|
|
86
|
+
/** 具体问题列表 */
|
|
87
|
+
issues: string[];
|
|
88
|
+
/** 改进建议 */
|
|
89
|
+
suggestions: string[];
|
|
90
|
+
}
|
|
91
|
+
/** AI Provider 接口 */
|
|
92
|
+
interface AIProvider {
|
|
93
|
+
readonly name: string;
|
|
94
|
+
readonly capabilities: AICapability;
|
|
95
|
+
generateTest(req: AIGenerateTestRequest): Promise<AIGenerateTestResponse>;
|
|
96
|
+
analyzeResult(req: AIAnalyzeResultRequest): Promise<AIAnalyzeResultResponse>;
|
|
97
|
+
suggestFix(error: TestError): Promise<string[]>;
|
|
98
|
+
reviewTest(req: AIReviewTestRequest): Promise<AIReviewTestResponse>;
|
|
99
|
+
}
|
|
100
|
+
/** AI 配置 */
|
|
101
|
+
interface AIConfig {
|
|
102
|
+
provider: string;
|
|
103
|
+
apiKey?: string;
|
|
104
|
+
model?: string;
|
|
105
|
+
baseUrl?: string;
|
|
106
|
+
}
|
|
107
|
+
/** 预置 Provider 配置(用于 init 向导) */
|
|
108
|
+
interface AIPresetProvider {
|
|
109
|
+
/** 标识名 */
|
|
110
|
+
id: string;
|
|
111
|
+
/** 显示名 */
|
|
112
|
+
name: string;
|
|
113
|
+
/** 默认 base URL */
|
|
114
|
+
baseUrl: string;
|
|
115
|
+
/** 默认模型 */
|
|
116
|
+
defaultModel: string;
|
|
117
|
+
/** 是否需要 API Key */
|
|
118
|
+
requiresApiKey: boolean;
|
|
119
|
+
}
|
|
120
|
+
|
|
1
121
|
/**
|
|
2
122
|
* QAT 全局类型定义
|
|
3
123
|
*/
|
|
@@ -161,126 +281,6 @@ interface SetupOptions extends GlobalOptions {
|
|
|
161
281
|
dryRun?: boolean;
|
|
162
282
|
}
|
|
163
283
|
|
|
164
|
-
/**
|
|
165
|
-
* AI 相关类型定义
|
|
166
|
-
*/
|
|
167
|
-
|
|
168
|
-
/** AI 能力标识 */
|
|
169
|
-
interface AICapability {
|
|
170
|
-
generateTest: boolean;
|
|
171
|
-
analyzeResult: boolean;
|
|
172
|
-
suggestFix: boolean;
|
|
173
|
-
}
|
|
174
|
-
/** 源码分析摘要(传给 AI 的精简版) */
|
|
175
|
-
interface SourceAnalysisSummary {
|
|
176
|
-
/** 导出项摘要 */
|
|
177
|
-
exports: Array<{
|
|
178
|
-
name: string;
|
|
179
|
-
kind: string;
|
|
180
|
-
params?: string[];
|
|
181
|
-
isAsync?: boolean;
|
|
182
|
-
}>;
|
|
183
|
-
/** Vue Props */
|
|
184
|
-
props?: Array<{
|
|
185
|
-
name: string;
|
|
186
|
-
type: string;
|
|
187
|
-
required: boolean;
|
|
188
|
-
}>;
|
|
189
|
-
/** Vue Emits */
|
|
190
|
-
emits?: Array<{
|
|
191
|
-
name: string;
|
|
192
|
-
params?: string[];
|
|
193
|
-
}>;
|
|
194
|
-
/** Options API 方法 */
|
|
195
|
-
methods?: string[];
|
|
196
|
-
/** computed 属性 */
|
|
197
|
-
computed?: string[];
|
|
198
|
-
}
|
|
199
|
-
/** AI 生成测试请求 */
|
|
200
|
-
interface AIGenerateTestRequest {
|
|
201
|
-
type: TestType;
|
|
202
|
-
target: string;
|
|
203
|
-
context?: string;
|
|
204
|
-
framework?: 'vue';
|
|
205
|
-
/** 源码分析摘要 */
|
|
206
|
-
analysis?: SourceAnalysisSummary;
|
|
207
|
-
}
|
|
208
|
-
/** AI 生成测试响应 */
|
|
209
|
-
interface AIGenerateTestResponse {
|
|
210
|
-
code: string;
|
|
211
|
-
description: string;
|
|
212
|
-
confidence: number;
|
|
213
|
-
}
|
|
214
|
-
/** AI 分析结果请求 */
|
|
215
|
-
interface AIAnalyzeResultRequest {
|
|
216
|
-
testResults: TestRunResult[];
|
|
217
|
-
errorLogs?: string[];
|
|
218
|
-
screenshots?: string[];
|
|
219
|
-
}
|
|
220
|
-
/** AI 分析结果响应 */
|
|
221
|
-
interface AIAnalyzeResultResponse {
|
|
222
|
-
analysis: string;
|
|
223
|
-
suggestions: string[];
|
|
224
|
-
severity: 'info' | 'warning' | 'error';
|
|
225
|
-
}
|
|
226
|
-
/** AI 审计测试请求 */
|
|
227
|
-
interface AIReviewTestRequest {
|
|
228
|
-
/** 被测源码文件路径 */
|
|
229
|
-
target: string;
|
|
230
|
-
/** 被测源码内容 */
|
|
231
|
-
sourceCode: string;
|
|
232
|
-
/** 源码分析摘要 */
|
|
233
|
-
analysis?: SourceAnalysisSummary;
|
|
234
|
-
/** 生成的测试代码 */
|
|
235
|
-
testCode: string;
|
|
236
|
-
/** 测试类型 */
|
|
237
|
-
testType: TestType;
|
|
238
|
-
/** 生成者 AI 的描述/意图 */
|
|
239
|
-
generationDescription?: string;
|
|
240
|
-
}
|
|
241
|
-
/** AI 审计测试响应 */
|
|
242
|
-
interface AIReviewTestResponse {
|
|
243
|
-
/** 是否通过审计 */
|
|
244
|
-
approved: boolean;
|
|
245
|
-
/** 审计评分 0-1 */
|
|
246
|
-
score: number;
|
|
247
|
-
/** 审计意见 */
|
|
248
|
-
feedback: string;
|
|
249
|
-
/** 具体问题列表 */
|
|
250
|
-
issues: string[];
|
|
251
|
-
/** 改进建议 */
|
|
252
|
-
suggestions: string[];
|
|
253
|
-
}
|
|
254
|
-
/** AI Provider 接口 */
|
|
255
|
-
interface AIProvider {
|
|
256
|
-
readonly name: string;
|
|
257
|
-
readonly capabilities: AICapability;
|
|
258
|
-
generateTest(req: AIGenerateTestRequest): Promise<AIGenerateTestResponse>;
|
|
259
|
-
analyzeResult(req: AIAnalyzeResultRequest): Promise<AIAnalyzeResultResponse>;
|
|
260
|
-
suggestFix(error: TestError): Promise<string[]>;
|
|
261
|
-
reviewTest(req: AIReviewTestRequest): Promise<AIReviewTestResponse>;
|
|
262
|
-
}
|
|
263
|
-
/** AI 配置 */
|
|
264
|
-
interface AIConfig {
|
|
265
|
-
provider: string;
|
|
266
|
-
apiKey?: string;
|
|
267
|
-
model?: string;
|
|
268
|
-
baseUrl?: string;
|
|
269
|
-
}
|
|
270
|
-
/** 预置 Provider 配置(用于 init 向导) */
|
|
271
|
-
interface AIPresetProvider {
|
|
272
|
-
/** 标识名 */
|
|
273
|
-
id: string;
|
|
274
|
-
/** 显示名 */
|
|
275
|
-
name: string;
|
|
276
|
-
/** 默认 base URL */
|
|
277
|
-
baseUrl: string;
|
|
278
|
-
/** 默认模型 */
|
|
279
|
-
defaultModel: string;
|
|
280
|
-
/** 是否需要 API Key */
|
|
281
|
-
requiresApiKey: boolean;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
284
|
/**
|
|
285
285
|
* 配置管理服务 - 读取/解析/校验/生成 qat.config.ts
|
|
286
286
|
*/
|
|
@@ -738,6 +738,14 @@ declare class OpenAICompatibleProvider implements AIProvider {
|
|
|
738
738
|
private chat;
|
|
739
739
|
private buildGenerateTestSystemPrompt;
|
|
740
740
|
private buildGenerateTestUserPrompt;
|
|
741
|
+
/**
|
|
742
|
+
* 根据测试类型和源文件路径,计算从测试文件到源文件的正确相对导入路径
|
|
743
|
+
*/
|
|
744
|
+
private computeTestImportPath;
|
|
745
|
+
/**
|
|
746
|
+
* 获取测试输出目录
|
|
747
|
+
*/
|
|
748
|
+
private getTestOutputDir;
|
|
741
749
|
private parseGenerateTestResponse;
|
|
742
750
|
private buildReviewTestSystemPrompt;
|
|
743
751
|
private buildReviewTestUserPrompt;
|
package/dist/index.js
CHANGED
|
@@ -955,12 +955,36 @@ Handlebars.registerHelper("propTestValue", (prop) => {
|
|
|
955
955
|
};
|
|
956
956
|
return map[prop.type] || "'test-value'";
|
|
957
957
|
});
|
|
958
|
+
function resolveImportPath(testType, targetPath) {
|
|
959
|
+
if (!targetPath) return targetPath;
|
|
960
|
+
const testDirMap = {
|
|
961
|
+
unit: "tests/unit",
|
|
962
|
+
component: "tests/component",
|
|
963
|
+
e2e: "tests/e2e",
|
|
964
|
+
api: "tests/api",
|
|
965
|
+
visual: "tests/visual",
|
|
966
|
+
performance: "tests/e2e"
|
|
967
|
+
};
|
|
968
|
+
const testDir = testDirMap[testType];
|
|
969
|
+
if (!testDir) return targetPath;
|
|
970
|
+
if (targetPath.startsWith("../") || targetPath.startsWith("./../")) {
|
|
971
|
+
return targetPath;
|
|
972
|
+
}
|
|
973
|
+
const depth = testDir.split("/").length;
|
|
974
|
+
const prefix = "../".repeat(depth);
|
|
975
|
+
let cleanPath = targetPath.replace(/^\.\//, "");
|
|
976
|
+
if (!cleanPath.endsWith(".vue")) {
|
|
977
|
+
cleanPath = cleanPath.replace(/\.(ts|js|tsx|jsx)$/, "");
|
|
978
|
+
}
|
|
979
|
+
return `${prefix}${cleanPath}`;
|
|
980
|
+
}
|
|
958
981
|
function registerTemplate(type, templateContent) {
|
|
959
982
|
customTemplates.set(type, templateContent);
|
|
960
983
|
}
|
|
961
984
|
function renderTemplate(type, context) {
|
|
962
985
|
const templateContent = loadTemplate(type);
|
|
963
986
|
const template = Handlebars.compile(templateContent);
|
|
987
|
+
const resolvedTarget = resolveImportPath(type, context.target);
|
|
964
988
|
const fullContext = {
|
|
965
989
|
vueVersion: 3,
|
|
966
990
|
typescript: true,
|
|
@@ -981,6 +1005,8 @@ function renderTemplate(type, context) {
|
|
|
981
1005
|
requiredProps: [],
|
|
982
1006
|
optionalProps: [],
|
|
983
1007
|
...context,
|
|
1008
|
+
// 使用计算后的正确路径
|
|
1009
|
+
target: resolvedTarget,
|
|
984
1010
|
framework: context.framework || "vue",
|
|
985
1011
|
camelName: context.camelName || toCamelCase(context.name),
|
|
986
1012
|
pascalName: context.pascalName || toPascalCase(context.name)
|
|
@@ -1682,14 +1708,14 @@ function buildVitestArgs(options) {
|
|
|
1682
1708
|
if (options.files && options.files.length > 0) {
|
|
1683
1709
|
args.push(...options.files);
|
|
1684
1710
|
} else {
|
|
1685
|
-
const
|
|
1686
|
-
unit:
|
|
1687
|
-
component:
|
|
1688
|
-
api:
|
|
1711
|
+
const pathMap = {
|
|
1712
|
+
unit: "tests/unit/**/*.test.ts",
|
|
1713
|
+
component: "tests/component/**/*.test.ts",
|
|
1714
|
+
api: "tests/api/**/*.test.ts"
|
|
1689
1715
|
};
|
|
1690
|
-
const
|
|
1691
|
-
if (
|
|
1692
|
-
args.push(
|
|
1716
|
+
const testPattern = pathMap[options.type];
|
|
1717
|
+
if (testPattern) {
|
|
1718
|
+
args.push(testPattern);
|
|
1693
1719
|
}
|
|
1694
1720
|
}
|
|
1695
1721
|
if (options.coverage) {
|
|
@@ -2672,8 +2698,13 @@ ${error.actual ? `\u5B9E\u9645\u503C: ${error.actual}` : ""}`;
|
|
|
2672
2698
|
6. \u5982\u679C\u6709 props/emits \u4FE1\u606F\uFF0C\u52A1\u5FC5\u9488\u5BF9\u6BCF\u4E2A prop \u548C emit \u751F\u6210\u6D4B\u8BD5`;
|
|
2673
2699
|
}
|
|
2674
2700
|
buildGenerateTestUserPrompt(req) {
|
|
2701
|
+
const importPath = this.computeTestImportPath(req.type, req.target);
|
|
2675
2702
|
let prompt = `\u8BF7\u4E3A\u4EE5\u4E0B\u6587\u4EF6\u751F\u6210${req.type}\u6D4B\u8BD5\u4EE3\u7801:
|
|
2676
2703
|
\u76EE\u6807\u6587\u4EF6: ${req.target}
|
|
2704
|
+
\u6D4B\u8BD5\u6587\u4EF6\u5C06\u653E\u5728: ${this.getTestOutputDir(req.type)}/
|
|
2705
|
+
\u6B63\u786E\u7684 import \u8DEF\u5F84: ${importPath}
|
|
2706
|
+
|
|
2707
|
+
\u91CD\u8981\uFF1Aimport \u8BED\u53E5\u4E2D\u5FC5\u987B\u4F7F\u7528\u4E0A\u8FF0\u6B63\u786E\u7684\u76F8\u5BF9\u8DEF\u5F84 ${importPath}\uFF0C\u4E0D\u8981\u4F7F\u7528 ${req.target} \u6216\u5176\u4ED6\u8DEF\u5F84\uFF01
|
|
2677
2708
|
`;
|
|
2678
2709
|
if (req.analysis) {
|
|
2679
2710
|
prompt += "\n\u6E90\u7801\u5206\u6790\u7ED3\u679C:\n";
|
|
@@ -2723,6 +2754,46 @@ ${req.context}
|
|
|
2723
2754
|
}
|
|
2724
2755
|
return prompt;
|
|
2725
2756
|
}
|
|
2757
|
+
/**
|
|
2758
|
+
* 根据测试类型和源文件路径,计算从测试文件到源文件的正确相对导入路径
|
|
2759
|
+
*/
|
|
2760
|
+
computeTestImportPath(testType, targetPath) {
|
|
2761
|
+
if (!targetPath) return targetPath;
|
|
2762
|
+
const testDirMap = {
|
|
2763
|
+
unit: "tests/unit",
|
|
2764
|
+
component: "tests/component",
|
|
2765
|
+
e2e: "tests/e2e",
|
|
2766
|
+
api: "tests/api",
|
|
2767
|
+
visual: "tests/visual",
|
|
2768
|
+
performance: "tests/e2e"
|
|
2769
|
+
};
|
|
2770
|
+
const testDir = testDirMap[testType];
|
|
2771
|
+
if (!testDir) return targetPath;
|
|
2772
|
+
if (targetPath.startsWith("../") || targetPath.startsWith("./../")) {
|
|
2773
|
+
return targetPath;
|
|
2774
|
+
}
|
|
2775
|
+
const depth = testDir.split("/").length;
|
|
2776
|
+
const prefix = "../".repeat(depth);
|
|
2777
|
+
let cleanPath = targetPath.replace(/^\.\//, "");
|
|
2778
|
+
if (!cleanPath.endsWith(".vue")) {
|
|
2779
|
+
cleanPath = cleanPath.replace(/\.(ts|js|tsx|jsx)$/, "");
|
|
2780
|
+
}
|
|
2781
|
+
return `${prefix}${cleanPath}`;
|
|
2782
|
+
}
|
|
2783
|
+
/**
|
|
2784
|
+
* 获取测试输出目录
|
|
2785
|
+
*/
|
|
2786
|
+
getTestOutputDir(testType) {
|
|
2787
|
+
const dirMap = {
|
|
2788
|
+
unit: "tests/unit",
|
|
2789
|
+
component: "tests/component",
|
|
2790
|
+
e2e: "tests/e2e",
|
|
2791
|
+
api: "tests/api",
|
|
2792
|
+
visual: "tests/visual",
|
|
2793
|
+
performance: "tests/e2e"
|
|
2794
|
+
};
|
|
2795
|
+
return dirMap[testType] || "tests/unit";
|
|
2796
|
+
}
|
|
2726
2797
|
parseGenerateTestResponse(content) {
|
|
2727
2798
|
const codeBlockMatch = content.match(/```(?:typescript|ts|javascript|js)?\s*\n([\s\S]*?)```/);
|
|
2728
2799
|
const code = codeBlockMatch ? codeBlockMatch[1].trim() : content.replace(/^(?:```[\s\S]*?\n)?/, "").replace(/\n?```$/, "").trim();
|
|
@@ -2751,10 +2822,12 @@ ISSUES: \u95EE\u9898\u5217\u8868\uFF08\u6BCF\u884C\u4E00\u4E2A\uFF0C\u683C\u5F0F
|
|
|
2751
2822
|
SUGGESTIONS: \u6539\u8FDB\u5EFA\u8BAE\u5217\u8868\uFF08\u6BCF\u884C\u4E00\u4E2A\uFF0C\u683C\u5F0F "- \u5EFA\u8BAE\u63CF\u8FF0"\uFF09`;
|
|
2752
2823
|
}
|
|
2753
2824
|
buildReviewTestUserPrompt(req) {
|
|
2825
|
+
const importPath = this.computeTestImportPath(req.testType, req.target);
|
|
2754
2826
|
let prompt = `\u8BF7\u5BA1\u67E5\u4EE5\u4E0B\u6D4B\u8BD5\u7528\u4F8B\u662F\u5426\u4E0E\u6E90\u7801\u8D34\u5207\u4E14\u51C6\u786E\u3002
|
|
2755
2827
|
|
|
2756
2828
|
\u88AB\u6D4B\u6587\u4EF6: ${req.target}
|
|
2757
2829
|
\u6D4B\u8BD5\u7C7B\u578B: ${req.testType}
|
|
2830
|
+
\u6B63\u786E\u7684 import \u8DEF\u5F84\u5E94\u4E3A: ${importPath}\uFF08\u6D4B\u8BD5\u6587\u4EF6\u4F4D\u4E8E ${this.getTestOutputDir(req.testType)}/\uFF09
|
|
2758
2831
|
|
|
2759
2832
|
--- \u6E90\u7801\u5185\u5BB9 ---
|
|
2760
2833
|
\`\`\`typescript
|