Skip to content

Commit 3ac9a7a

Browse files
authored
test: add test for args (#160)
1 parent da0b247 commit 3ac9a7a

File tree

2 files changed

+140
-1
lines changed

2 files changed

+140
-1
lines changed

src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export type BooleanArgDef = Omit<_ArgDef<"boolean", boolean>, "options"> & {
2424
negativeDescription?: string;
2525
};
2626
export type StringArgDef = Omit<_ArgDef<"string", string>, "options">;
27-
export type NumberArgDef = Omit<_ArgDef<"number", boolean>, "options">;
27+
export type NumberArgDef = Omit<_ArgDef<"number", number>, "options">;
2828
export type EnumArgDef = _ArgDef<"enum", string>;
2929
export type PositionalArgDef = Omit<
3030
_ArgDef<"positional", string>,

test/args.test.ts

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import { describe, it, expect } from "vitest";
2+
import { parseArgs } from "../src/args";
3+
import { ArgsDef, ParsedArgs } from "../src";
4+
5+
describe("args", () => {
6+
it.each<[string[], ArgsDef, ParsedArgs]>([
7+
[[], {}, { _: [] }],
8+
/**
9+
* String
10+
*/
11+
[["--name", "John"], { name: { type: "string" } }, { name: "John", _: [] }],
12+
[
13+
[],
14+
{ name: { type: "string", default: "John" } },
15+
{ name: "John", _: [] },
16+
],
17+
[
18+
["--name", "Jane"],
19+
{ name: { type: "string", default: "John" } },
20+
{ name: "Jane", _: [] },
21+
],
22+
[
23+
["-n", "Jane"],
24+
{ name: { type: "string", alias: "n" } },
25+
{ name: "Jane", n: "Jane", _: [] },
26+
],
27+
/**
28+
* Number
29+
*/
30+
[["--age", "25"], { age: { type: "number" } }, { age: 25, _: [] }],
31+
[[], { age: { type: "number", default: 25 } }, { age: 25, _: [] }],
32+
[
33+
["--age", "30"],
34+
{ age: { type: "number", default: 25 } },
35+
{ age: 30, _: [] },
36+
],
37+
[
38+
["-a", "30"],
39+
{ age: { type: "number", alias: "a" } },
40+
{ age: 30, a: "30", _: [] },
41+
],
42+
/**
43+
* Boolean
44+
*/
45+
[["--force"], { force: { type: "boolean" } }, { force: true, _: [] }],
46+
[
47+
["-f"],
48+
{ force: { alias: "f", type: "boolean" } },
49+
{ force: true, f: true, _: [] },
50+
],
51+
[[], { force: { type: "boolean", default: true } }, { force: true, _: [] }],
52+
[
53+
["--no-force"],
54+
{ force: { type: "boolean", negativeDescription: "force" } },
55+
{ force: false, _: [] },
56+
],
57+
/**
58+
* Positional
59+
*/
60+
[
61+
["subCommand"],
62+
{ command: { type: "positional" } },
63+
{ _: ["subCommand"], command: "subCommand" },
64+
],
65+
[
66+
[],
67+
{ command: { type: "positional", default: "subCommand" } },
68+
{ _: [], command: "subCommand" },
69+
],
70+
[[], { command: { type: "positional", required: false } }, { _: [] }],
71+
/**
72+
* Enum
73+
*/
74+
[
75+
["--value", "one"],
76+
{ value: { type: "enum", options: ["one", "two"] } },
77+
{ value: "one", _: [] },
78+
],
79+
])("should parsed correctly %o (%o)", (rawArgs, definition, result) => {
80+
const parsed = parseArgs(rawArgs, definition);
81+
82+
expect(parsed).toEqual(result);
83+
});
84+
85+
it.each<[string[], ArgsDef, string]>([
86+
[
87+
[],
88+
{ name: { type: "string", required: true } },
89+
"Missing required argument: --name",
90+
],
91+
[
92+
["--age", "twenty-five"],
93+
{ age: { type: "number" } },
94+
"Invalid value for argument: `--age` (`twenty-five`). Expected a number.",
95+
],
96+
[
97+
[],
98+
{
99+
name: { type: "positional" },
100+
},
101+
"Missing required positional argument: NAME",
102+
],
103+
[
104+
["--value", "three"],
105+
{ value: { type: "enum", options: ["one", "two"] } },
106+
"Invalid value for argument: `--value` (`three`). Expected one of: `one`, `two`.",
107+
],
108+
])("should throw error with %o (%o)", (rawArgs, definition, result) => {
109+
// TODO: should check for exact match
110+
// https://github.com/vitest-dev/vitest/discussions/6048
111+
expect(() => {
112+
parseArgs(rawArgs, definition);
113+
}).toThrowError(result);
114+
});
115+
116+
it("should resolve camelCase argument", () => {
117+
const definition: ArgsDef = {
118+
"user-name": { type: "string" },
119+
};
120+
const rawArgs = ["--userName", "Jane"];
121+
122+
const parsed = parseArgs(rawArgs, definition);
123+
124+
expect(parsed["user-name"]).toBe("Jane");
125+
expect(parsed._).toEqual([]);
126+
});
127+
128+
it("should resolve kebab-case argument", () => {
129+
const definition: ArgsDef = {
130+
userName: { type: "string" },
131+
};
132+
const rawArgs = ["--user-name", "Jane"];
133+
134+
const parsed = parseArgs(rawArgs, definition);
135+
136+
expect(parsed.userName).toBe("Jane");
137+
expect(parsed._).toEqual([]);
138+
});
139+
});

0 commit comments

Comments
 (0)