@zjex/git-workflow 0.3.7 → 0.3.9

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.
@@ -43,8 +43,6 @@ describe("Init 模块测试", () => {
43
43
  beforeEach(() => {
44
44
  vi.clearAllMocks();
45
45
  vi.spyOn(console, "log").mockImplementation(() => {});
46
-
47
- // Default mocks
48
46
  mockHomedir.mockReturnValue("/home/user");
49
47
  mockJoin.mockReturnValue("/home/user/.gwrc.json");
50
48
  });
@@ -56,28 +54,25 @@ describe("Init 模块测试", () => {
56
54
  describe("配置范围选择", () => {
57
55
  it("应该支持全局配置", async () => {
58
56
  mockExistsSync.mockReturnValue(false);
59
-
60
57
  const { select, input } = await import("@inquirer/prompts");
61
58
  vi.mocked(select)
62
- .mockResolvedValueOnce("global") // 配置范围
63
- .mockResolvedValueOnce(false) // requireId
64
- .mockResolvedValueOnce("ask") // autoPush
65
- .mockResolvedValueOnce(true) // autoStage
66
- .mockResolvedValueOnce(true) // useEmoji
67
- .mockResolvedValueOnce(false); // enableAI
68
-
59
+ .mockResolvedValueOnce("global")
60
+ .mockResolvedValueOnce(false)
61
+ .mockResolvedValueOnce(false)
62
+ .mockResolvedValueOnce(false)
63
+ .mockResolvedValueOnce("ask")
64
+ .mockResolvedValueOnce(true)
65
+ .mockResolvedValueOnce(true)
66
+ .mockResolvedValueOnce(false);
69
67
  vi.mocked(input)
70
- .mockResolvedValueOnce("") // baseBranch
71
- .mockResolvedValueOnce("feature") // featurePrefix
72
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
73
- .mockResolvedValueOnce("Story ID") // featureIdLabel
74
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
75
- .mockResolvedValueOnce(""); // defaultTagPrefix
76
-
68
+ .mockResolvedValueOnce("")
69
+ .mockResolvedValueOnce("feature")
70
+ .mockResolvedValueOnce("hotfix")
71
+ .mockResolvedValueOnce("Story ID")
72
+ .mockResolvedValueOnce("Issue ID")
73
+ .mockResolvedValueOnce("");
77
74
  const { init } = await import("../src/commands/init.js");
78
-
79
75
  await init();
80
-
81
76
  expect(mockJoin).toHaveBeenCalledWith("/home/user", ".gwrc.json");
82
77
  expect(mockWriteFileSync).toHaveBeenCalledWith(
83
78
  "/home/user/.gwrc.json",
@@ -87,28 +82,25 @@ describe("Init 模块测试", () => {
87
82
 
88
83
  it("应该支持项目配置", async () => {
89
84
  mockExistsSync.mockReturnValue(false);
90
-
91
85
  const { select, input } = await import("@inquirer/prompts");
92
86
  vi.mocked(select)
93
- .mockResolvedValueOnce("project") // 配置范围
94
- .mockResolvedValueOnce(false) // requireId
95
- .mockResolvedValueOnce("ask") // autoPush
96
- .mockResolvedValueOnce(true) // autoStage
97
- .mockResolvedValueOnce(true) // useEmoji
98
- .mockResolvedValueOnce(false); // enableAI
99
-
87
+ .mockResolvedValueOnce("project")
88
+ .mockResolvedValueOnce(false)
89
+ .mockResolvedValueOnce(false)
90
+ .mockResolvedValueOnce(false)
91
+ .mockResolvedValueOnce("ask")
92
+ .mockResolvedValueOnce(true)
93
+ .mockResolvedValueOnce(true)
94
+ .mockResolvedValueOnce(false);
100
95
  vi.mocked(input)
101
- .mockResolvedValueOnce("") // baseBranch
102
- .mockResolvedValueOnce("feature") // featurePrefix
103
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
104
- .mockResolvedValueOnce("Story ID") // featureIdLabel
105
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
106
- .mockResolvedValueOnce(""); // defaultTagPrefix
107
-
96
+ .mockResolvedValueOnce("")
97
+ .mockResolvedValueOnce("feature")
98
+ .mockResolvedValueOnce("hotfix")
99
+ .mockResolvedValueOnce("Story ID")
100
+ .mockResolvedValueOnce("Issue ID")
101
+ .mockResolvedValueOnce("");
108
102
  const { init } = await import("../src/commands/init.js");
109
-
110
103
  await init();
111
-
112
104
  expect(mockWriteFileSync).toHaveBeenCalledWith(
113
105
  ".gwrc.json",
114
106
  expect.stringContaining('"featurePrefix": "feature"')
@@ -119,44 +111,37 @@ describe("Init 模块测试", () => {
119
111
  describe("配置文件覆盖", () => {
120
112
  it("应该处理配置文件已存在的情况", async () => {
121
113
  mockExistsSync.mockReturnValue(true);
122
-
123
114
  const { select, input } = await import("@inquirer/prompts");
124
115
  vi.mocked(select)
125
- .mockResolvedValueOnce("global") // 配置范围
126
- .mockResolvedValueOnce(true) // 覆盖文件
127
- .mockResolvedValueOnce(false) // requireId
128
- .mockResolvedValueOnce("ask") // autoPush
129
- .mockResolvedValueOnce(true) // autoStage
130
- .mockResolvedValueOnce(true) // useEmoji
131
- .mockResolvedValueOnce(false); // enableAI
132
-
116
+ .mockResolvedValueOnce("global")
117
+ .mockResolvedValueOnce(true)
118
+ .mockResolvedValueOnce(false)
119
+ .mockResolvedValueOnce(false)
120
+ .mockResolvedValueOnce(false)
121
+ .mockResolvedValueOnce("ask")
122
+ .mockResolvedValueOnce(true)
123
+ .mockResolvedValueOnce(true)
124
+ .mockResolvedValueOnce(false);
133
125
  vi.mocked(input)
134
- .mockResolvedValueOnce("") // baseBranch
135
- .mockResolvedValueOnce("feature") // featurePrefix
136
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
137
- .mockResolvedValueOnce("Story ID") // featureIdLabel
138
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
139
- .mockResolvedValueOnce(""); // defaultTagPrefix
140
-
126
+ .mockResolvedValueOnce("")
127
+ .mockResolvedValueOnce("feature")
128
+ .mockResolvedValueOnce("hotfix")
129
+ .mockResolvedValueOnce("Story ID")
130
+ .mockResolvedValueOnce("Issue ID")
131
+ .mockResolvedValueOnce("");
141
132
  const { init } = await import("../src/commands/init.js");
142
-
143
133
  await init();
144
-
145
134
  expect(mockWriteFileSync).toHaveBeenCalled();
146
135
  });
147
136
 
148
137
  it("应该处理用户取消覆盖", async () => {
149
138
  mockExistsSync.mockReturnValue(true);
150
-
151
139
  const { select } = await import("@inquirer/prompts");
152
140
  vi.mocked(select)
153
- .mockResolvedValueOnce("global") // 配置范围
154
- .mockResolvedValueOnce(false); // 不覆盖文件
155
-
141
+ .mockResolvedValueOnce("global")
142
+ .mockResolvedValueOnce(false);
156
143
  const { init } = await import("../src/commands/init.js");
157
-
158
144
  await init();
159
-
160
145
  expect(console.log).toHaveBeenCalledWith("已取消");
161
146
  expect(mockWriteFileSync).not.toHaveBeenCalled();
162
147
  });
@@ -165,31 +150,27 @@ describe("Init 模块测试", () => {
165
150
  describe("基础配置", () => {
166
151
  it("应该正确配置分支前缀", async () => {
167
152
  mockExistsSync.mockReturnValue(false);
168
-
169
153
  const { select, input } = await import("@inquirer/prompts");
170
154
  vi.mocked(select)
171
- .mockResolvedValueOnce("project") // 配置范围
172
- .mockResolvedValueOnce(false) // requireId
173
- .mockResolvedValueOnce("ask") // autoPush
174
- .mockResolvedValueOnce(true) // autoStage
175
- .mockResolvedValueOnce(true) // useEmoji
176
- .mockResolvedValueOnce(false); // enableAI
177
-
155
+ .mockResolvedValueOnce("project")
156
+ .mockResolvedValueOnce(false)
157
+ .mockResolvedValueOnce(false)
158
+ .mockResolvedValueOnce(false)
159
+ .mockResolvedValueOnce("ask")
160
+ .mockResolvedValueOnce(true)
161
+ .mockResolvedValueOnce(true)
162
+ .mockResolvedValueOnce(false);
178
163
  vi.mocked(input)
179
- .mockResolvedValueOnce("develop") // baseBranch
180
- .mockResolvedValueOnce("feat") // featurePrefix
181
- .mockResolvedValueOnce("fix") // hotfixPrefix
182
- .mockResolvedValueOnce("Jira ID") // featureIdLabel
183
- .mockResolvedValueOnce("Bug ID") // hotfixIdLabel
184
- .mockResolvedValueOnce("v"); // defaultTagPrefix
185
-
164
+ .mockResolvedValueOnce("develop")
165
+ .mockResolvedValueOnce("feat")
166
+ .mockResolvedValueOnce("fix")
167
+ .mockResolvedValueOnce("Jira ID")
168
+ .mockResolvedValueOnce("Bug ID")
169
+ .mockResolvedValueOnce("v");
186
170
  const { init } = await import("../src/commands/init.js");
187
-
188
171
  await init();
189
-
190
172
  const writtenConfig = mockWriteFileSync.mock.calls[0][1] as string;
191
173
  const config = JSON.parse(writtenConfig);
192
-
193
174
  expect(config.baseBranch).toBe("develop");
194
175
  expect(config.featurePrefix).toBe("feat");
195
176
  expect(config.hotfixPrefix).toBe("fix");
@@ -200,61 +181,53 @@ describe("Init 模块测试", () => {
200
181
 
201
182
  it("应该正确配置 ID 要求", async () => {
202
183
  mockExistsSync.mockReturnValue(false);
203
-
204
184
  const { select, input } = await import("@inquirer/prompts");
205
185
  vi.mocked(select)
206
- .mockResolvedValueOnce("project") // 配置范围
207
- .mockResolvedValueOnce(true) // requireId
208
- .mockResolvedValueOnce("ask") // autoPush
209
- .mockResolvedValueOnce(true) // autoStage
210
- .mockResolvedValueOnce(true) // useEmoji
211
- .mockResolvedValueOnce(false); // enableAI
212
-
186
+ .mockResolvedValueOnce("project")
187
+ .mockResolvedValueOnce(true)
188
+ .mockResolvedValueOnce(false)
189
+ .mockResolvedValueOnce(false)
190
+ .mockResolvedValueOnce("ask")
191
+ .mockResolvedValueOnce(true)
192
+ .mockResolvedValueOnce(true)
193
+ .mockResolvedValueOnce(false);
213
194
  vi.mocked(input)
214
- .mockResolvedValueOnce("") // baseBranch
215
- .mockResolvedValueOnce("feature") // featurePrefix
216
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
217
- .mockResolvedValueOnce("Story ID") // featureIdLabel
218
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
219
- .mockResolvedValueOnce(""); // defaultTagPrefix
220
-
195
+ .mockResolvedValueOnce("")
196
+ .mockResolvedValueOnce("feature")
197
+ .mockResolvedValueOnce("hotfix")
198
+ .mockResolvedValueOnce("Story ID")
199
+ .mockResolvedValueOnce("Issue ID")
200
+ .mockResolvedValueOnce("");
221
201
  const { init } = await import("../src/commands/init.js");
222
-
223
202
  await init();
224
-
225
203
  const writtenConfig = mockWriteFileSync.mock.calls[0][1] as string;
226
204
  const config = JSON.parse(writtenConfig);
227
-
228
205
  expect(config.requireId).toBe(true);
229
206
  });
230
207
 
231
208
  it("应该正确配置自动推送选项", async () => {
232
209
  mockExistsSync.mockReturnValue(false);
233
-
234
210
  const { select, input } = await import("@inquirer/prompts");
235
211
  vi.mocked(select)
236
- .mockResolvedValueOnce("project") // 配置范围
237
- .mockResolvedValueOnce(false) // requireId
238
- .mockResolvedValueOnce("yes") // autoPush
239
- .mockResolvedValueOnce(true) // autoStage
240
- .mockResolvedValueOnce(true) // useEmoji
241
- .mockResolvedValueOnce(false); // enableAI
242
-
212
+ .mockResolvedValueOnce("project")
213
+ .mockResolvedValueOnce(false)
214
+ .mockResolvedValueOnce(false)
215
+ .mockResolvedValueOnce(false)
216
+ .mockResolvedValueOnce("yes")
217
+ .mockResolvedValueOnce(true)
218
+ .mockResolvedValueOnce(true)
219
+ .mockResolvedValueOnce(false);
243
220
  vi.mocked(input)
244
- .mockResolvedValueOnce("") // baseBranch
245
- .mockResolvedValueOnce("feature") // featurePrefix
246
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
247
- .mockResolvedValueOnce("Story ID") // featureIdLabel
248
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
249
- .mockResolvedValueOnce(""); // defaultTagPrefix
250
-
221
+ .mockResolvedValueOnce("")
222
+ .mockResolvedValueOnce("feature")
223
+ .mockResolvedValueOnce("hotfix")
224
+ .mockResolvedValueOnce("Story ID")
225
+ .mockResolvedValueOnce("Issue ID")
226
+ .mockResolvedValueOnce("");
251
227
  const { init } = await import("../src/commands/init.js");
252
-
253
228
  await init();
254
-
255
229
  const writtenConfig = mockWriteFileSync.mock.calls[0][1] as string;
256
230
  const config = JSON.parse(writtenConfig);
257
-
258
231
  expect(config.autoPush).toBe(true);
259
232
  });
260
233
  });
@@ -262,34 +235,32 @@ describe("Init 模块测试", () => {
262
235
  describe("AI 配置", () => {
263
236
  it("应该正确配置 GitHub Models", async () => {
264
237
  mockExistsSync.mockReturnValue(false);
265
-
266
238
  const { select, input } = await import("@inquirer/prompts");
267
239
  vi.mocked(select)
268
- .mockResolvedValueOnce("project") // 配置范围
269
- .mockResolvedValueOnce(false) // requireId
270
- .mockResolvedValueOnce("ask") // autoPush
271
- .mockResolvedValueOnce(true) // autoStage
272
- .mockResolvedValueOnce(true) // useEmoji
273
- .mockResolvedValueOnce(true) // enableAI
274
- .mockResolvedValueOnce("github") // AI provider
275
- .mockResolvedValueOnce("zh-CN"); // language
276
-
240
+ .mockResolvedValueOnce("project")
241
+ .mockResolvedValueOnce(false)
242
+ .mockResolvedValueOnce(false)
243
+ .mockResolvedValueOnce(false)
244
+ .mockResolvedValueOnce("ask")
245
+ .mockResolvedValueOnce(true)
246
+ .mockResolvedValueOnce(true)
247
+ .mockResolvedValueOnce(true)
248
+ .mockResolvedValueOnce("github")
249
+ .mockResolvedValueOnce("zh-CN")
250
+ .mockResolvedValueOnce(true)
251
+ .mockResolvedValueOnce(true);
277
252
  vi.mocked(input)
278
- .mockResolvedValueOnce("") // baseBranch
279
- .mockResolvedValueOnce("feature") // featurePrefix
280
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
281
- .mockResolvedValueOnce("Story ID") // featureIdLabel
282
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
283
- .mockResolvedValueOnce("") // defaultTagPrefix
284
- .mockResolvedValueOnce("ghp_test_token"); // GitHub token
285
-
253
+ .mockResolvedValueOnce("")
254
+ .mockResolvedValueOnce("feature")
255
+ .mockResolvedValueOnce("hotfix")
256
+ .mockResolvedValueOnce("Story ID")
257
+ .mockResolvedValueOnce("Issue ID")
258
+ .mockResolvedValueOnce("")
259
+ .mockResolvedValueOnce("ghp_test_token");
286
260
  const { init } = await import("../src/commands/init.js");
287
-
288
261
  await init();
289
-
290
262
  const writtenConfig = mockWriteFileSync.mock.calls[0][1] as string;
291
263
  const config = JSON.parse(writtenConfig);
292
-
293
264
  expect(config.aiCommit.enabled).toBe(true);
294
265
  expect(config.aiCommit.provider).toBe("github");
295
266
  expect(config.aiCommit.apiKey).toBe("ghp_test_token");
@@ -299,34 +270,32 @@ describe("Init 模块测试", () => {
299
270
 
300
271
  it("应该正确配置 OpenAI", async () => {
301
272
  mockExistsSync.mockReturnValue(false);
302
-
303
273
  const { select, input } = await import("@inquirer/prompts");
304
274
  vi.mocked(select)
305
- .mockResolvedValueOnce("project") // 配置范围
306
- .mockResolvedValueOnce(false) // requireId
307
- .mockResolvedValueOnce("ask") // autoPush
308
- .mockResolvedValueOnce(true) // autoStage
309
- .mockResolvedValueOnce(true) // useEmoji
310
- .mockResolvedValueOnce(true) // enableAI
311
- .mockResolvedValueOnce("openai") // AI provider
312
- .mockResolvedValueOnce("en-US"); // language
313
-
275
+ .mockResolvedValueOnce("project")
276
+ .mockResolvedValueOnce(false)
277
+ .mockResolvedValueOnce(false)
278
+ .mockResolvedValueOnce(false)
279
+ .mockResolvedValueOnce("ask")
280
+ .mockResolvedValueOnce(true)
281
+ .mockResolvedValueOnce(true)
282
+ .mockResolvedValueOnce(true)
283
+ .mockResolvedValueOnce("openai")
284
+ .mockResolvedValueOnce("en-US")
285
+ .mockResolvedValueOnce(true)
286
+ .mockResolvedValueOnce(true);
314
287
  vi.mocked(input)
315
- .mockResolvedValueOnce("") // baseBranch
316
- .mockResolvedValueOnce("feature") // featurePrefix
317
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
318
- .mockResolvedValueOnce("Story ID") // featureIdLabel
319
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
320
- .mockResolvedValueOnce("") // defaultTagPrefix
321
- .mockResolvedValueOnce("sk-test-key"); // OpenAI API key
322
-
288
+ .mockResolvedValueOnce("")
289
+ .mockResolvedValueOnce("feature")
290
+ .mockResolvedValueOnce("hotfix")
291
+ .mockResolvedValueOnce("Story ID")
292
+ .mockResolvedValueOnce("Issue ID")
293
+ .mockResolvedValueOnce("")
294
+ .mockResolvedValueOnce("sk-test-key");
323
295
  const { init } = await import("../src/commands/init.js");
324
-
325
296
  await init();
326
-
327
297
  const writtenConfig = mockWriteFileSync.mock.calls[0][1] as string;
328
298
  const config = JSON.parse(writtenConfig);
329
-
330
299
  expect(config.aiCommit.enabled).toBe(true);
331
300
  expect(config.aiCommit.provider).toBe("openai");
332
301
  expect(config.aiCommit.apiKey).toBe("sk-test-key");
@@ -336,33 +305,31 @@ describe("Init 模块测试", () => {
336
305
 
337
306
  it("应该正确配置 Ollama", async () => {
338
307
  mockExistsSync.mockReturnValue(false);
339
-
340
308
  const { select, input } = await import("@inquirer/prompts");
341
309
  vi.mocked(select)
342
- .mockResolvedValueOnce("project") // 配置范围
343
- .mockResolvedValueOnce(false) // requireId
344
- .mockResolvedValueOnce("ask") // autoPush
345
- .mockResolvedValueOnce(true) // autoStage
346
- .mockResolvedValueOnce(true) // useEmoji
347
- .mockResolvedValueOnce(true) // enableAI
348
- .mockResolvedValueOnce("ollama") // AI provider
349
- .mockResolvedValueOnce("zh-CN"); // language
350
-
310
+ .mockResolvedValueOnce("project")
311
+ .mockResolvedValueOnce(false)
312
+ .mockResolvedValueOnce(false)
313
+ .mockResolvedValueOnce(false)
314
+ .mockResolvedValueOnce("ask")
315
+ .mockResolvedValueOnce(true)
316
+ .mockResolvedValueOnce(true)
317
+ .mockResolvedValueOnce(true)
318
+ .mockResolvedValueOnce("ollama")
319
+ .mockResolvedValueOnce("zh-CN")
320
+ .mockResolvedValueOnce(true)
321
+ .mockResolvedValueOnce(true);
351
322
  vi.mocked(input)
352
- .mockResolvedValueOnce("") // baseBranch
353
- .mockResolvedValueOnce("feature") // featurePrefix
354
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
355
- .mockResolvedValueOnce("Story ID") // featureIdLabel
356
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
357
- .mockResolvedValueOnce(""); // defaultTagPrefix
358
-
323
+ .mockResolvedValueOnce("")
324
+ .mockResolvedValueOnce("feature")
325
+ .mockResolvedValueOnce("hotfix")
326
+ .mockResolvedValueOnce("Story ID")
327
+ .mockResolvedValueOnce("Issue ID")
328
+ .mockResolvedValueOnce("");
359
329
  const { init } = await import("../src/commands/init.js");
360
-
361
330
  await init();
362
-
363
331
  const writtenConfig = mockWriteFileSync.mock.calls[0][1] as string;
364
332
  const config = JSON.parse(writtenConfig);
365
-
366
333
  expect(config.aiCommit.enabled).toBe(true);
367
334
  expect(config.aiCommit.provider).toBe("ollama");
368
335
  expect(config.aiCommit.apiKey).toBeUndefined();
@@ -372,31 +339,27 @@ describe("Init 模块测试", () => {
372
339
 
373
340
  it("应该正确配置禁用 AI", async () => {
374
341
  mockExistsSync.mockReturnValue(false);
375
-
376
342
  const { select, input } = await import("@inquirer/prompts");
377
343
  vi.mocked(select)
378
- .mockResolvedValueOnce("project") // 配置范围
379
- .mockResolvedValueOnce(false) // requireId
380
- .mockResolvedValueOnce("ask") // autoPush
381
- .mockResolvedValueOnce(true) // autoStage
382
- .mockResolvedValueOnce(true) // useEmoji
383
- .mockResolvedValueOnce(false); // enableAI
384
-
344
+ .mockResolvedValueOnce("project")
345
+ .mockResolvedValueOnce(false)
346
+ .mockResolvedValueOnce(false)
347
+ .mockResolvedValueOnce(false)
348
+ .mockResolvedValueOnce("ask")
349
+ .mockResolvedValueOnce(true)
350
+ .mockResolvedValueOnce(true)
351
+ .mockResolvedValueOnce(false);
385
352
  vi.mocked(input)
386
- .mockResolvedValueOnce("") // baseBranch
387
- .mockResolvedValueOnce("feature") // featurePrefix
388
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
389
- .mockResolvedValueOnce("Story ID") // featureIdLabel
390
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
391
- .mockResolvedValueOnce(""); // defaultTagPrefix
392
-
353
+ .mockResolvedValueOnce("")
354
+ .mockResolvedValueOnce("feature")
355
+ .mockResolvedValueOnce("hotfix")
356
+ .mockResolvedValueOnce("Story ID")
357
+ .mockResolvedValueOnce("Issue ID")
358
+ .mockResolvedValueOnce("");
393
359
  const { init } = await import("../src/commands/init.js");
394
-
395
360
  await init();
396
-
397
361
  const writtenConfig = mockWriteFileSync.mock.calls[0][1] as string;
398
362
  const config = JSON.parse(writtenConfig);
399
-
400
363
  expect(config.aiCommit.enabled).toBe(false);
401
364
  });
402
365
  });
@@ -404,41 +367,36 @@ describe("Init 模块测试", () => {
404
367
  describe("配置验证", () => {
405
368
  it("应该验证 GitHub Token 不为空", async () => {
406
369
  mockExistsSync.mockReturnValue(false);
407
-
408
370
  const { select, input } = await import("@inquirer/prompts");
409
371
  vi.mocked(select)
410
- .mockResolvedValueOnce("project") // 配置范围
411
- .mockResolvedValueOnce(false) // requireId
412
- .mockResolvedValueOnce("ask") // autoPush
413
- .mockResolvedValueOnce(true) // autoStage
414
- .mockResolvedValueOnce(true) // useEmoji
415
- .mockResolvedValueOnce(true) // enableAI
416
- .mockResolvedValueOnce("github") // AI provider
417
- .mockResolvedValueOnce("zh-CN"); // language
418
-
372
+ .mockResolvedValueOnce("project")
373
+ .mockResolvedValueOnce(false)
374
+ .mockResolvedValueOnce(false)
375
+ .mockResolvedValueOnce(false)
376
+ .mockResolvedValueOnce("ask")
377
+ .mockResolvedValueOnce(true)
378
+ .mockResolvedValueOnce(true)
379
+ .mockResolvedValueOnce(true)
380
+ .mockResolvedValueOnce("github")
381
+ .mockResolvedValueOnce("zh-CN")
382
+ .mockResolvedValueOnce(true)
383
+ .mockResolvedValueOnce(true);
419
384
  vi.mocked(input)
420
- .mockResolvedValueOnce("") // baseBranch
421
- .mockResolvedValueOnce("feature") // featurePrefix
422
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
423
- .mockResolvedValueOnce("Story ID") // featureIdLabel
424
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
425
- .mockResolvedValueOnce("") // defaultTagPrefix
426
- .mockResolvedValueOnce("ghp_valid_token"); // GitHub token
427
-
385
+ .mockResolvedValueOnce("")
386
+ .mockResolvedValueOnce("feature")
387
+ .mockResolvedValueOnce("hotfix")
388
+ .mockResolvedValueOnce("Story ID")
389
+ .mockResolvedValueOnce("Issue ID")
390
+ .mockResolvedValueOnce("")
391
+ .mockResolvedValueOnce("ghp_valid_token");
428
392
  const { init } = await import("../src/commands/init.js");
429
-
430
393
  await init();
431
-
432
- // 验证 input 被调用时包含验证函数
433
394
  const inputCalls = vi.mocked(input).mock.calls;
434
- const tokenInputCall = inputCalls.find(call =>
395
+ const tokenInputCall = inputCalls.find((call) =>
435
396
  call[0].message?.includes("GitHub Token")
436
397
  );
437
-
438
398
  expect(tokenInputCall).toBeDefined();
439
399
  expect(tokenInputCall![0].validate).toBeDefined();
440
-
441
- // 测试验证函数
442
400
  const validate = tokenInputCall![0].validate!;
443
401
  expect(validate("")).toBe("GitHub Token 不能为空");
444
402
  expect(validate("valid-token")).toBe(true);
@@ -446,41 +404,36 @@ describe("Init 模块测试", () => {
446
404
 
447
405
  it("应该验证 OpenAI API Key 不为空", async () => {
448
406
  mockExistsSync.mockReturnValue(false);
449
-
450
407
  const { select, input } = await import("@inquirer/prompts");
451
408
  vi.mocked(select)
452
- .mockResolvedValueOnce("project") // 配置范围
453
- .mockResolvedValueOnce(false) // requireId
454
- .mockResolvedValueOnce("ask") // autoPush
455
- .mockResolvedValueOnce(true) // autoStage
456
- .mockResolvedValueOnce(true) // useEmoji
457
- .mockResolvedValueOnce(true) // enableAI
458
- .mockResolvedValueOnce("openai") // AI provider
459
- .mockResolvedValueOnce("en-US"); // language
460
-
409
+ .mockResolvedValueOnce("project")
410
+ .mockResolvedValueOnce(false)
411
+ .mockResolvedValueOnce(false)
412
+ .mockResolvedValueOnce(false)
413
+ .mockResolvedValueOnce("ask")
414
+ .mockResolvedValueOnce(true)
415
+ .mockResolvedValueOnce(true)
416
+ .mockResolvedValueOnce(true)
417
+ .mockResolvedValueOnce("openai")
418
+ .mockResolvedValueOnce("en-US")
419
+ .mockResolvedValueOnce(true)
420
+ .mockResolvedValueOnce(true);
461
421
  vi.mocked(input)
462
- .mockResolvedValueOnce("") // baseBranch
463
- .mockResolvedValueOnce("feature") // featurePrefix
464
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
465
- .mockResolvedValueOnce("Story ID") // featureIdLabel
466
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
467
- .mockResolvedValueOnce("") // defaultTagPrefix
468
- .mockResolvedValueOnce("sk-valid-key"); // OpenAI API key
469
-
422
+ .mockResolvedValueOnce("")
423
+ .mockResolvedValueOnce("feature")
424
+ .mockResolvedValueOnce("hotfix")
425
+ .mockResolvedValueOnce("Story ID")
426
+ .mockResolvedValueOnce("Issue ID")
427
+ .mockResolvedValueOnce("")
428
+ .mockResolvedValueOnce("sk-valid-key");
470
429
  const { init } = await import("../src/commands/init.js");
471
-
472
430
  await init();
473
-
474
- // 验证 input 被调用时包含验证函数
475
431
  const inputCalls = vi.mocked(input).mock.calls;
476
- const keyInputCall = inputCalls.find(call =>
432
+ const keyInputCall = inputCalls.find((call) =>
477
433
  call[0].message?.includes("OpenAI API Key")
478
434
  );
479
-
480
435
  expect(keyInputCall).toBeDefined();
481
436
  expect(keyInputCall![0].validate).toBeDefined();
482
-
483
- // 测试验证函数
484
437
  const validate = keyInputCall![0].validate!;
485
438
  expect(validate("")).toBe("API Key 不能为空");
486
439
  expect(validate("valid-key")).toBe(true);
@@ -490,31 +443,27 @@ describe("Init 模块测试", () => {
490
443
  describe("配置输出", () => {
491
444
  it("应该包含默认的 commit emojis", async () => {
492
445
  mockExistsSync.mockReturnValue(false);
493
-
494
446
  const { select, input } = await import("@inquirer/prompts");
495
447
  vi.mocked(select)
496
- .mockResolvedValueOnce("project") // 配置范围
497
- .mockResolvedValueOnce(false) // requireId
498
- .mockResolvedValueOnce("ask") // autoPush
499
- .mockResolvedValueOnce(true) // autoStage
500
- .mockResolvedValueOnce(true) // useEmoji
501
- .mockResolvedValueOnce(false); // enableAI
502
-
448
+ .mockResolvedValueOnce("project")
449
+ .mockResolvedValueOnce(false)
450
+ .mockResolvedValueOnce(false)
451
+ .mockResolvedValueOnce(false)
452
+ .mockResolvedValueOnce("ask")
453
+ .mockResolvedValueOnce(true)
454
+ .mockResolvedValueOnce(true)
455
+ .mockResolvedValueOnce(false);
503
456
  vi.mocked(input)
504
- .mockResolvedValueOnce("") // baseBranch
505
- .mockResolvedValueOnce("feature") // featurePrefix
506
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
507
- .mockResolvedValueOnce("Story ID") // featureIdLabel
508
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
509
- .mockResolvedValueOnce(""); // defaultTagPrefix
510
-
457
+ .mockResolvedValueOnce("")
458
+ .mockResolvedValueOnce("feature")
459
+ .mockResolvedValueOnce("hotfix")
460
+ .mockResolvedValueOnce("Story ID")
461
+ .mockResolvedValueOnce("Issue ID")
462
+ .mockResolvedValueOnce("");
511
463
  const { init } = await import("../src/commands/init.js");
512
-
513
464
  await init();
514
-
515
465
  const writtenConfig = mockWriteFileSync.mock.calls[0][1] as string;
516
466
  const config = JSON.parse(writtenConfig);
517
-
518
467
  expect(config.commitEmojis).toBeDefined();
519
468
  expect(config.commitEmojis.feat).toBe("✨");
520
469
  expect(config.commitEmojis.fix).toBe("🐛");
@@ -523,28 +472,25 @@ describe("Init 模块测试", () => {
523
472
 
524
473
  it("应该显示成功消息", async () => {
525
474
  mockExistsSync.mockReturnValue(false);
526
-
527
475
  const { select, input } = await import("@inquirer/prompts");
528
476
  vi.mocked(select)
529
- .mockResolvedValueOnce("global") // 配置范围
530
- .mockResolvedValueOnce(false) // requireId
531
- .mockResolvedValueOnce("ask") // autoPush
532
- .mockResolvedValueOnce(true) // autoStage
533
- .mockResolvedValueOnce(true) // useEmoji
534
- .mockResolvedValueOnce(false); // enableAI
535
-
477
+ .mockResolvedValueOnce("global")
478
+ .mockResolvedValueOnce(false)
479
+ .mockResolvedValueOnce(false)
480
+ .mockResolvedValueOnce(false)
481
+ .mockResolvedValueOnce("ask")
482
+ .mockResolvedValueOnce(true)
483
+ .mockResolvedValueOnce(true)
484
+ .mockResolvedValueOnce(false);
536
485
  vi.mocked(input)
537
- .mockResolvedValueOnce("") // baseBranch
538
- .mockResolvedValueOnce("feature") // featurePrefix
539
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
540
- .mockResolvedValueOnce("Story ID") // featureIdLabel
541
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
542
- .mockResolvedValueOnce(""); // defaultTagPrefix
543
-
486
+ .mockResolvedValueOnce("")
487
+ .mockResolvedValueOnce("feature")
488
+ .mockResolvedValueOnce("hotfix")
489
+ .mockResolvedValueOnce("Story ID")
490
+ .mockResolvedValueOnce("Issue ID")
491
+ .mockResolvedValueOnce("");
544
492
  const { init } = await import("../src/commands/init.js");
545
-
546
493
  await init();
547
-
548
494
  expect(console.log).toHaveBeenCalledWith(
549
495
  expect.stringContaining("✓ 配置已保存到 全局配置文件")
550
496
  );
@@ -552,31 +498,28 @@ describe("Init 模块测试", () => {
552
498
 
553
499
  it("应该显示全局配置的提示信息", async () => {
554
500
  mockExistsSync.mockReturnValue(false);
555
-
556
501
  const { select, input } = await import("@inquirer/prompts");
557
502
  vi.mocked(select)
558
- .mockResolvedValueOnce("global") // 配置范围
559
- .mockResolvedValueOnce(false) // requireId
560
- .mockResolvedValueOnce("ask") // autoPush
561
- .mockResolvedValueOnce(true) // autoStage
562
- .mockResolvedValueOnce(true) // useEmoji
563
- .mockResolvedValueOnce(false); // enableAI
564
-
503
+ .mockResolvedValueOnce("global")
504
+ .mockResolvedValueOnce(false)
505
+ .mockResolvedValueOnce(false)
506
+ .mockResolvedValueOnce(false)
507
+ .mockResolvedValueOnce("ask")
508
+ .mockResolvedValueOnce(true)
509
+ .mockResolvedValueOnce(true)
510
+ .mockResolvedValueOnce(false);
565
511
  vi.mocked(input)
566
- .mockResolvedValueOnce("") // baseBranch
567
- .mockResolvedValueOnce("feature") // featurePrefix
568
- .mockResolvedValueOnce("hotfix") // hotfixPrefix
569
- .mockResolvedValueOnce("Story ID") // featureIdLabel
570
- .mockResolvedValueOnce("Issue ID") // hotfixIdLabel
571
- .mockResolvedValueOnce(""); // defaultTagPrefix
572
-
512
+ .mockResolvedValueOnce("")
513
+ .mockResolvedValueOnce("feature")
514
+ .mockResolvedValueOnce("hotfix")
515
+ .mockResolvedValueOnce("Story ID")
516
+ .mockResolvedValueOnce("Issue ID")
517
+ .mockResolvedValueOnce("");
573
518
  const { init } = await import("../src/commands/init.js");
574
-
575
519
  await init();
576
-
577
520
  expect(console.log).toHaveBeenCalledWith(
578
521
  expect.stringContaining("全局配置对所有项目生效")
579
522
  );
580
523
  });
581
524
  });
582
- });
525
+ });