Skip to content

Commit df89ede

Browse files
committed
test(e2e): align with UsageError validation contract
Missing required flags now throw UsageError (exit code 2, error on stderr, JSON under --output json) instead of printing help and exiting 0. Update assertions and titles accordingly: - missing-flag cases: exitCode 0/1 -> 2, retitle to "errors as usage error (2)" - auth / video-task-get under --output json: assert the error JSON on stderr - proxy probe: import setupProxyFromEnv from runtime/src/proxy.ts - drop tests for the removed config export-schema command - fix t2v dry-run: cliTimeoutPrefix misplaced between --model and its value
1 parent 1f56fea commit df89ede

23 files changed

Lines changed: 66 additions & 110 deletions

packages/cli/tests/e2e/advisor-recommend.e2e.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ describe("e2e: advisor recommend", () => {
1616
});
1717

1818
describe.skipIf(!isDashScopeE2EReady())("e2e: advisor recommend (DashScope)", () => {
19-
test("advisor recommend without --message prints help and exits", async () => {
19+
test("advisor recommend without --message errors as usage error (2)", async () => {
2020
const { stdout, stderr, exitCode } = await runCli([
2121
"advisor",
2222
"recommend",
2323
"--non-interactive",
2424
]);
25-
expect(exitCode).toBe(0);
25+
expect(exitCode).toBe(2);
2626
expect(`${stdout}\n${stderr}`).toMatch(/--message|Usage:/i);
2727
});
2828

packages/cli/tests/e2e/auth.e2e.test.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ describe("e2e: auth", () => {
3232
expect(stderr).toMatch(/status|output/i);
3333
});
3434

35-
test("auth login 缺少 --api-key 时打印子命令帮助并退出 (0)", async () => {
35+
test("auth login 缺少 --api-key 时报用法错误并退出 (2)", async () => {
3636
const { stderr, exitCode } = await runCli(["auth", "login", "--non-interactive"]);
37-
expect(exitCode, stderr).toBe(0);
37+
expect(exitCode, stderr).toBe(2);
3838
expect(stderr).toMatch(/--api-key|Usage:/i);
3939
});
4040

@@ -69,16 +69,18 @@ describe("e2e: auth", () => {
6969
expect(stdout).toContain("Would validate and save API key.");
7070
});
7171

72-
test("auth login 缺少密钥且 --output json 时仍打印子命令帮助 (0)", async () => {
72+
test("auth login 缺少密钥且 --output json 时报用法错误并退出 (2)", async () => {
7373
const { stderr, exitCode } = await runCli([
7474
"auth",
7575
"login",
7676
"--non-interactive",
7777
"--output",
7878
"json",
7979
]);
80-
expect(exitCode).toBe(0);
81-
expect(stderr).toMatch(/--api-key|Usage:/i);
80+
expect(exitCode).toBe(2);
81+
const err = JSON.parse(stderr.trim()) as { error?: { code?: number; message?: string } };
82+
expect(err.error?.code).toBe(2);
83+
expect(err.error?.message).toMatch(/--api-key|console/i);
8284
});
8385

8486
test("auth logout --dry-run 不写入配置", async () => {

packages/cli/tests/e2e/config.e2e.test.ts

Lines changed: 3 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe("e2e: config", () => {
1010
const { stdout, stderr, exitCode } = await runCli(["config"]);
1111
expect(exitCode, stderr).toBe(0);
1212
const out = `${stdout}\n${stderr}`;
13-
expect(out).toMatch(/config|show|set|export-schema/i);
13+
expect(out).toMatch(/config|show|set/i);
1414
});
1515

1616
test("config show --help 正常退出", async () => {
@@ -25,12 +25,6 @@ describe("e2e: config", () => {
2525
expect(stderr).toMatch(/set|--key|--value/i);
2626
});
2727

28-
test("config export-schema --help 正常退出", async () => {
29-
const { stderr, exitCode } = await runCli(["config", "export-schema", "--help"]);
30-
expect(exitCode, stderr).toBe(0);
31-
expect(stderr).toMatch(/export-schema|--command/i);
32-
});
33-
3428
test("config show --output json", async () => {
3529
const { stdout, stderr, exitCode } = await runCli([
3630
"config",
@@ -63,9 +57,9 @@ describe("e2e: config", () => {
6357
expect(stdout).toMatch(/config_file|timeout|base_url/i);
6458
});
6559

66-
test("config set 缺少 --key / --value 时打印子命令帮助并退出 (0)", async () => {
60+
test("config set 缺少 --key / --value 时报用法错误并退出 (2)", async () => {
6761
const { stderr, exitCode } = await runCli(["config", "set", "--non-interactive"]);
68-
expect(exitCode, stderr).toBe(0);
62+
expect(exitCode, stderr).toBe(2);
6963
expect(stderr).toMatch(/--key|--value|Usage:/i);
7064
});
7165

@@ -146,46 +140,4 @@ describe("e2e: config", () => {
146140
const data = parseStdoutJson<{ would_set?: { default_text_model?: string } }>(stdout);
147141
expect(data.would_set?.default_text_model).toBe("qwen3.7-max");
148142
});
149-
150-
test("config export-schema --command 导出单条工具 JSON", async () => {
151-
const { stdout, stderr, exitCode } = await runCli([
152-
"config",
153-
"export-schema",
154-
"--command",
155-
"text chat",
156-
"--non-interactive",
157-
]);
158-
expect(exitCode, stderr).toBe(0);
159-
const schema = parseStdoutJson<{ name?: string; input_schema?: { type?: string } }>(stdout);
160-
expect(schema.name).toMatch(/bailian_text_chat/);
161-
expect(schema.input_schema?.type).toBe("object");
162-
});
163-
164-
test("config export-schema 不存在的子命令时报错", async () => {
165-
const { stderr, exitCode } = await runCli([
166-
"config",
167-
"export-schema",
168-
"--command",
169-
"this-command-does-not-exist-xyz",
170-
"--non-interactive",
171-
"--output",
172-
"json",
173-
]);
174-
expect(exitCode).toBe(2);
175-
const err = JSON.parse(stderr.trim()) as { error?: { message?: string } };
176-
expect(err.error?.message).toMatch(/not found/i);
177-
});
178-
179-
test("config export-schema 导出全部为 JSON 数组", async () => {
180-
const { stdout, stderr, exitCode } = await runCli([
181-
"config",
182-
"export-schema",
183-
"--non-interactive",
184-
]);
185-
expect(exitCode, stderr).toBe(0);
186-
const arr = parseStdoutJson<Array<{ name?: string }>>(stdout);
187-
expect(Array.isArray(arr)).toBe(true);
188-
expect(arr.length).toBeGreaterThan(0);
189-
expect(arr[0]?.name).toMatch(/^bailian_/);
190-
});
191143
});

packages/cli/tests/e2e/file-upload.e2e.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@ describe("e2e: file upload", () => {
2525
});
2626

2727
describe.skipIf(!isDashScopeE2EReady())("e2e: file upload(DashScope)", () => {
28-
test("file upload 缺少 --file 时打印子命令帮助并退出 (0)", async () => {
28+
test("file upload 缺少 --file 时报用法错误并退出 (2)", async () => {
2929
const { stderr, exitCode } = await runCli([
3030
"file",
3131
"upload",
3232
"--model",
3333
"qwen3-vl-plus",
3434
"--non-interactive",
3535
]);
36-
expect(exitCode).toBe(0);
36+
expect(exitCode).toBe(2);
3737
expect(stderr).toMatch(/--file|Usage:/i);
3838
});
3939

40-
test("file upload 缺少 --model 时打印子命令帮助并退出 (0)", async () => {
40+
test("file upload 缺少 --model 时报用法错误并退出 (2)", async () => {
4141
const testFile = join(__dirname, ".smoke-32.png");
4242
const { stderr, exitCode } = await runCli([
4343
"file",
@@ -46,7 +46,7 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: file upload(DashScope)", () =>
4646
testFile,
4747
"--non-interactive",
4848
]);
49-
expect(exitCode).toBe(0);
49+
expect(exitCode).toBe(2);
5050
expect(stderr).toMatch(/--model|Usage:/i);
5151
});
5252

packages/cli/tests/e2e/image-edit.e2e.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,19 @@ describe("e2e: image edit", () => {
3232
});
3333

3434
describe.skipIf(!isBailianE2EMediaEnabled() || !isDashScopeE2EReady())("e2e: image edit", () => {
35-
test("image edit 缺少 --image 时打印子命令帮助并退出 (0)", async () => {
35+
test("image edit 缺少 --image 时报用法错误并退出 (2)", async () => {
3636
const { stderr, exitCode } = await runCli([
3737
"image",
3838
"edit",
3939
"--prompt",
4040
"仅提示词",
4141
"--non-interactive",
4242
]);
43-
expect(exitCode).toBe(0);
43+
expect(exitCode).toBe(2);
4444
expect(stderr).toMatch(/--image|Usage:/i);
4545
});
4646

47-
test("image edit 缺少 --prompt 时打印子命令帮助并退出 (0)", async () => {
47+
test("image edit 缺少 --prompt 时报用法错误并退出 (2)", async () => {
4848
const testPng = join(__dirname, ".smoke-32.png");
4949
const { stderr, exitCode } = await runCli([
5050
"image",
@@ -53,7 +53,7 @@ describe.skipIf(!isBailianE2EMediaEnabled() || !isDashScopeE2EReady())("e2e: ima
5353
testPng,
5454
"--non-interactive",
5555
]);
56-
expect(exitCode).toBe(0);
56+
expect(exitCode).toBe(2);
5757
expect(stderr).toMatch(/--prompt|Usage:/i);
5858
});
5959

packages/cli/tests/e2e/image-generate.e2e.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ describe("e2e: image generate", () => {
3232
describe.skipIf(!isBailianE2EMediaEnabled() || !isDashScopeE2EReady())(
3333
"e2e: image generate",
3434
() => {
35-
test("image generate 缺少 --prompt 时打印子命令帮助并退出 (0)", async () => {
35+
test("image generate 缺少 --prompt 时报用法错误并退出 (2)", async () => {
3636
const { stderr, exitCode } = await runCli([
3737
"image",
3838
"generate",
3939
"--model",
4040
"qwen-image-2.0",
4141
"--non-interactive",
4242
]);
43-
expect(exitCode).toBe(0);
43+
expect(exitCode).toBe(2);
4444
expect(stderr).toMatch(/--prompt|Usage:/i);
4545
});
4646

packages/cli/tests/e2e/knowledge.e2e.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,27 +37,27 @@ describe("e2e: knowledge retrieve", () => {
3737
expect(stderr).toMatch(/deprecated/i);
3838
});
3939

40-
test("缺少 --index-id 时打印帮助并退出 (0)", async () => {
40+
test("缺少 --index-id 时报用法错误并退出 (2)", async () => {
4141
const { stderr, exitCode } = await runCli([
4242
"knowledge",
4343
"retrieve",
4444
"--query",
4545
"test",
4646
"--non-interactive",
4747
]);
48-
expect(exitCode).toBe(0);
48+
expect(exitCode).toBe(2);
4949
expect(stderr).toMatch(/--index-id|Usage:/i);
5050
});
5151

52-
test("缺少 --query 时打印帮助并退出 (0)", async () => {
52+
test("缺少 --query 时报用法错误并退出 (2)", async () => {
5353
const { stderr, exitCode } = await runCli([
5454
"knowledge",
5555
"retrieve",
5656
"--index-id",
5757
"idx_test",
5858
"--non-interactive",
5959
]);
60-
expect(exitCode).toBe(0);
60+
expect(exitCode).toBe(2);
6161
expect(stderr).toMatch(/--query|Usage:/i);
6262
});
6363
});

packages/cli/tests/e2e/mcp.e2e.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ describe("e2e: mcp", () => {
142142
expect(data.url).toBe("https://example.com/custom/mcp");
143143
});
144144

145-
test("mcp tools 缺少 --server 时打印子命令帮助并退出 (0)", async () => {
145+
test("mcp tools 缺少 --server 时报用法错误并退出 (2)", async () => {
146146
const { stderr, exitCode } = await runCli(["mcp", "tools", "--non-interactive"]);
147-
expect(exitCode, stderr).toBe(0);
147+
expect(exitCode, stderr).toBe(2);
148148
expect(stderr).toMatch(/--server|Usage:/i);
149149
});
150150

@@ -258,9 +258,9 @@ describe("e2e: mcp", () => {
258258
expect(stderr).toMatch(/--json is not valid JSON|--json must decode/);
259259
});
260260

261-
test("mcp call 缺少 --target 时打印子命令帮助并退出 (0)", async () => {
261+
test("mcp call 缺少 --target 时报用法错误并退出 (2)", async () => {
262262
const { stderr, exitCode } = await runCli(["mcp", "call", "--non-interactive"]);
263-
expect(exitCode, stderr).toBe(0);
263+
expect(exitCode, stderr).toBe(2);
264264
expect(stderr).toMatch(/--target|Usage:/i);
265265
});
266266
});

packages/cli/tests/e2e/memory.e2e.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ describe("e2e: memory", () => {
6969
describe.skipIf(!isBailianE2EEnabled() || !isDashScopeE2EReady())(
7070
"e2e: memory CRUD + search",
7171
() => {
72-
test("memory add 缺少 --user-id 时打印子命令帮助并退出 (0)", async () => {
72+
test("memory add 缺少 --user-id 时报用法错误并退出 (2)", async () => {
7373
const { stderr, exitCode } = await runCli([
7474
"memory",
7575
"add",
@@ -78,7 +78,7 @@ describe.skipIf(!isBailianE2EEnabled() || !isDashScopeE2EReady())(
7878
"仅内容无用户",
7979
"--non-interactive",
8080
]);
81-
expect(exitCode).toBe(0);
81+
expect(exitCode).toBe(2);
8282
expect(stderr).toMatch(/--user-id|Usage:/i);
8383
});
8484

@@ -92,7 +92,7 @@ describe.skipIf(!isBailianE2EEnabled() || !isDashScopeE2EReady())(
9292
userId,
9393
"--non-interactive",
9494
]);
95-
expect(exitCode).toBe(1);
95+
expect(exitCode).toBe(2);
9696
expect(stderr).toMatch(/messages|content|required/i);
9797
});
9898

packages/cli/tests/e2e/omni.e2e.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ describe("e2e: omni", () => {
2020
describe.skipIf(!isBailianE2EMediaEnabled() || !isDashScopeE2EReady())(
2121
"e2e: omni(DashScope 媒体)",
2222
() => {
23-
test("omni 缺少 --message 时打印子命令帮助并退出 (0)", async () => {
23+
test("omni 缺少 --message 时报用法错误并退出 (2)", async () => {
2424
const { stderr, exitCode } = await runCli([
2525
"omni",
2626
"--model",
2727
"qwen3.5-omni-flash",
2828
"--non-interactive",
2929
]);
30-
expect(exitCode).toBe(0);
30+
expect(exitCode).toBe(2);
3131
expect(stderr).toMatch(/--message|Usage:/i);
3232
});
3333

0 commit comments

Comments
 (0)