diff --git a/src/args.ts b/src/args.ts index 3642a12..3e37952 100644 --- a/src/args.ts +++ b/src/args.ts @@ -131,7 +131,11 @@ export function parseFlags(argv: string[], options: OptionDef[]): GlobalFlags { if (arr) arr.push(value); else (flags as Record)[camelKey] = [value]; } else if (schema.numbers.has(camelKey)) { - (flags as Record)[camelKey] = Number(value); + const numericValue = Number(value); + if (value.trim() === '' || !Number.isFinite(numericValue)) { + throw new Error(`Flag --${key} requires a numeric value, got "${value}".`); + } + (flags as Record)[camelKey] = numericValue; } else { (flags as Record)[camelKey] = value; } diff --git a/test/args.test.ts b/test/args.test.ts new file mode 100644 index 0000000..e71ac2c --- /dev/null +++ b/test/args.test.ts @@ -0,0 +1,28 @@ +import { describe, it, expect } from 'bun:test'; +import { parseFlags } from '../src/args'; +import type { OptionDef } from '../src/command'; + +const OPTIONS: OptionDef[] = [ + { flag: '--timeout ', description: 'Request timeout', type: 'number' }, + { flag: '--message ', description: 'Message text', type: 'array' }, +]; + +describe('parseFlags', () => { + it('rejects non-numeric values for number flags', () => { + expect(() => parseFlags(['--timeout', 'abc'], OPTIONS)).toThrow( + 'Flag --timeout requires a numeric value, got "abc".', + ); + }); + + it('rejects empty values for number flags', () => { + expect(() => parseFlags(['--timeout='], OPTIONS)).toThrow( + 'Flag --timeout requires a numeric value, got "".', + ); + }); + + it('still accepts finite numeric values', () => { + const flags = parseFlags(['--timeout', '1.5'], OPTIONS); + + expect(flags.timeout).toBe(1.5); + }); +});