feat: Fix the null value verification of the flag

This commit is contained in:
qcq01083097
2026-06-05 11:14:17 +08:00
parent ce59e2bd08
commit 99ef96d209
2 changed files with 61 additions and 4 deletions
+7 -4
View File
@@ -147,20 +147,23 @@ export function parseFlags(argv: string[], options: OptionDef[]): GlobalFlags {
);
}
// Switch-style flags (--quiet, --dry-run): no value. Value flags need a non-flag next token.
if (schema.booleans.has(camelKey)) {
(flags as Record<string, unknown>)[camelKey] = true;
i++;
continue;
}
// --prompt <text>, --watermark <bool>, …
if (value === undefined) {
i++;
value = argv[i];
const next = argv[i];
if (next === undefined || next.startsWith("-")) {
throw new BailianError(`Flag --${key} requires a value.`, ExitCode.USAGE);
}
value = next;
}
if (value === undefined)
throw new BailianError(`Flag --${key} requires a value.`, ExitCode.USAGE);
if (schema.arrays.has(camelKey)) {
const arr = (flags as Record<string, unknown>)[camelKey] as string[] | undefined;
if (arr) arr.push(value);
+54
View File
@@ -7,6 +7,7 @@ const IMAGE_GENERATE_OPTIONS = [
{ flag: "--prompt <text>", description: "Image description", required: true },
{ flag: "--model <model>", description: "Model ID" },
{ flag: "--watermark <bool>", description: BOOL_FLAG_WATERMARK },
{ flag: "--no-wait", description: "Return task ID immediately without waiting" },
];
test("parseFlags rejects unknown long flags", () => {
@@ -39,3 +40,56 @@ test("parseFlags accepts defined command and global flags", () => {
expect(flags.prompt).toBe("cat");
expect(flags.watermark).toBe("false");
});
test("parseFlags rejects value flag when next token is another flag", () => {
const opts = [...GLOBAL_OPTIONS, ...IMAGE_GENERATE_OPTIONS];
for (const argv of [
["--watermark", "--prompt", "cat"],
["--watermark", "-h"],
["--prompt", "cat", "--watermark", "--model", "qwen-image-2.0"],
]) {
expect(() => parseFlags(argv, opts)).toThrowError(
expect.objectContaining({
name: "BailianError",
exitCode: ExitCode.USAGE,
message: expect.stringContaining("Flag --watermark requires a value"),
}),
);
}
});
test("parseFlags rejects trailing value flag without value", () => {
expect(() =>
parseFlags(["--prompt", "cat", "--watermark"], [...GLOBAL_OPTIONS, ...IMAGE_GENERATE_OPTIONS]),
).toThrowError(
expect.objectContaining({
message: expect.stringContaining("Flag --watermark requires a value"),
}),
);
});
test("parseFlags allows boolean flags without values adjacent to other flags", () => {
const opts = [...GLOBAL_OPTIONS, ...IMAGE_GENERATE_OPTIONS];
const flags = parseFlags(
["--quiet", "--dry-run", "--no-wait", "--prompt", "cat", "--watermark", "false"],
opts,
);
expect(flags.quiet).toBe(true);
expect(flags.dryRun).toBe(true);
expect(flags.noWait).toBe(true);
expect(flags.prompt).toBe("cat");
expect(flags.watermark).toBe("false");
});
test("parseFlags does not treat the next flag as a boolean flag value", () => {
const opts = [...GLOBAL_OPTIONS, ...IMAGE_GENERATE_OPTIONS];
expect(() => parseFlags(["--dry-run", "--prompt"], opts)).toThrowError(
expect.objectContaining({
message: expect.stringContaining("Flag --prompt requires a value"),
}),
);
// --dry-run is boolean: no value check; parsing continues to --prompt.
const flags = parseFlags(["--dry-run", "--prompt", "cat"], opts);
expect(flags.dryRun).toBe(true);
expect(flags.prompt).toBe("cat");
});