Skip to content

Commit 501b446

Browse files
authored
test: add test for usage (#161)
1 parent 000a54e commit 501b446

File tree

1 file changed

+307
-0
lines changed

1 file changed

+307
-0
lines changed

test/usage.test.ts

+307
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
import { expect, it, describe } from "vitest";
2+
import { renderUsage } from "../src/usage";
3+
import { defineCommand } from "../src";
4+
5+
describe("usage", () => {
6+
it("renders arguments", async () => {
7+
const command = defineCommand({
8+
meta: {
9+
name: "Commander",
10+
description: "A command",
11+
},
12+
args: {
13+
foo: {
14+
type: "string",
15+
required: true,
16+
description: "A foo",
17+
},
18+
bar: {
19+
alias: ["b"],
20+
type: "string",
21+
description: "A bar",
22+
},
23+
pos: {
24+
type: "positional",
25+
name: "pos",
26+
description: "A pos",
27+
},
28+
enum: {
29+
type: "enum",
30+
name: "enum",
31+
options: ["a", "b"],
32+
description: "An enum",
33+
},
34+
boolean: {
35+
type: "boolean",
36+
name: "boolean",
37+
description: "A boolean",
38+
},
39+
},
40+
});
41+
42+
const usage = await renderUsage(command);
43+
44+
expect(usage).toMatchInlineSnapshot(`
45+
"A command (Commander)
46+
47+
USAGE \`Commander [OPTIONS] --foo <POS>\`
48+
49+
ARGUMENTS
50+
51+
\`POS\` A pos
52+
53+
OPTIONS
54+
55+
\`--foo (required)\` A foo
56+
\`-b, --bar\` A bar
57+
\`--enum=<a|b>\` An enum
58+
\`--boolean\` A boolean
59+
"
60+
`);
61+
});
62+
63+
it("renders the negative description when a boolean default is true", async () => {
64+
const command = defineCommand({
65+
meta: {
66+
name: "Commander",
67+
description: "A command",
68+
},
69+
args: {
70+
boolean: {
71+
type: "boolean",
72+
name: "boolean",
73+
default: true,
74+
description: "A boolean",
75+
negativeDescription: "A negative boolean",
76+
},
77+
},
78+
});
79+
80+
const usage = await renderUsage(command);
81+
82+
expect(usage).toMatchInlineSnapshot(`
83+
"A command (Commander)
84+
85+
USAGE \`Commander [OPTIONS] \`
86+
87+
OPTIONS
88+
89+
\`--boolean\` A boolean
90+
\`--no-boolean\` A negative boolean
91+
"
92+
`);
93+
});
94+
95+
it('renders arguments hints when "valueHint" is provided', async () => {
96+
const command = defineCommand({
97+
meta: {
98+
name: "Commander",
99+
description: "A command",
100+
},
101+
args: {
102+
foo: {
103+
type: "string",
104+
description: "A foo",
105+
valueHint: "FOO",
106+
},
107+
},
108+
});
109+
110+
const usage = await renderUsage(command);
111+
112+
expect(usage).toMatchInlineSnapshot(`
113+
"A command (Commander)
114+
115+
USAGE \`Commander [OPTIONS] \`
116+
117+
OPTIONS
118+
119+
\`--foo=<FOO>\` A foo
120+
"
121+
`);
122+
});
123+
124+
it("renders the default value when provided", async () => {
125+
const command = defineCommand({
126+
meta: {
127+
name: "Commander",
128+
description: "A command",
129+
},
130+
args: {
131+
foo: {
132+
type: "string",
133+
description: "A foo",
134+
default: "bar",
135+
},
136+
},
137+
});
138+
139+
const usage = await renderUsage(command);
140+
141+
expect(usage).toMatchInlineSnapshot(`
142+
"A command (Commander)
143+
144+
USAGE \`Commander [OPTIONS] \`
145+
146+
OPTIONS
147+
148+
\`--foo="bar"\` A foo
149+
"
150+
`);
151+
});
152+
153+
it("renders subcommands", async () => {
154+
const command = defineCommand({
155+
meta: {
156+
name: "Commander",
157+
description: "A command",
158+
},
159+
subCommands: {
160+
sub: defineCommand({
161+
meta: {
162+
name: "Subcommander",
163+
description: "A subcommand",
164+
},
165+
}),
166+
},
167+
});
168+
169+
const usage = await renderUsage(command);
170+
171+
expect(usage).toMatchInlineSnapshot(`
172+
"A command (Commander)
173+
174+
USAGE \`Commander sub\`
175+
176+
COMMANDS
177+
178+
\`sub\` A subcommand
179+
180+
Use \`Commander <command> --help\` for more information about a command."
181+
`);
182+
});
183+
184+
it("renders both arguments and subcommands", async () => {
185+
const command = defineCommand({
186+
meta: {
187+
name: "Commander",
188+
description: "A command",
189+
},
190+
args: {
191+
foo: {
192+
required: true,
193+
description: "A foo",
194+
},
195+
},
196+
subCommands: {
197+
sub: defineCommand({
198+
meta: {
199+
name: "Subcommander",
200+
description: "A subcommand",
201+
},
202+
}),
203+
},
204+
});
205+
206+
const usage = await renderUsage(command);
207+
208+
expect(usage).toMatchInlineSnapshot(`
209+
"A command (Commander)
210+
211+
USAGE \`Commander [OPTIONS] --foo sub\`
212+
213+
OPTIONS
214+
215+
\`--foo (required)\` A foo
216+
217+
COMMANDS
218+
219+
\`sub\` A subcommand
220+
221+
Use \`Commander <command> --help\` for more information about a command."
222+
`);
223+
});
224+
225+
it("does not render hidden subcommands", async () => {
226+
const command = defineCommand({
227+
meta: {
228+
name: "Commander",
229+
description: "A command",
230+
},
231+
subCommands: {
232+
sub: defineCommand({
233+
meta: {
234+
name: "Subcommander",
235+
description: "A subcommand",
236+
hidden: true,
237+
},
238+
}),
239+
start: defineCommand({
240+
meta: {
241+
name: "Start",
242+
description: "A start",
243+
},
244+
}),
245+
},
246+
});
247+
248+
const usage = await renderUsage(command);
249+
250+
expect(usage).toMatchInlineSnapshot(`
251+
"A command (Commander)
252+
253+
USAGE \`Commander start\`
254+
255+
COMMANDS
256+
257+
\`start\` A start
258+
259+
Use \`Commander <command> --help\` for more information about a command."
260+
`);
261+
});
262+
263+
it("uses parents meta to explain how to run sub commands", async () => {
264+
const childCommand = defineCommand({
265+
meta: {
266+
name: "child-command",
267+
description: "A child command",
268+
},
269+
args: {
270+
foo: {
271+
type: "string",
272+
description: "A foo",
273+
},
274+
},
275+
subCommands: {
276+
"sub-command": defineCommand({}),
277+
},
278+
});
279+
280+
const parentCommand = defineCommand({
281+
meta: {
282+
name: "parent-command",
283+
},
284+
subCommands: {
285+
sub: childCommand,
286+
},
287+
});
288+
289+
const usage = await renderUsage(childCommand, parentCommand);
290+
291+
expect(usage).toMatchInlineSnapshot(`
292+
"A child command (parent-command child-command)
293+
294+
USAGE \`parent-command child-command [OPTIONS] sub-command\`
295+
296+
OPTIONS
297+
298+
\`--foo\` A foo
299+
300+
COMMANDS
301+
302+
\`sub-command\`
303+
304+
Use \`parent-command child-command <command> --help\` for more information about a command."
305+
`);
306+
});
307+
});

0 commit comments

Comments
 (0)