Skip to content

Commit bdafbf8

Browse files
committed
fix(readme): update quick start example
1 parent f24e683 commit bdafbf8

File tree

2 files changed

+93
-79
lines changed

2 files changed

+93
-79
lines changed

README.md

+34-2
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ Create the file that will run your CLI, perhaps at `./cli.js`:
136136
>
137137
> Both CJS and ESM source is acceptable!
138138
139+
<!-- example-region cli.js -->
140+
139141
```js
140142
#!/usr/bin/env node
141143

@@ -145,13 +147,17 @@ export default runProgram(import.meta.resolve('./commands'));
145147
146148
Then create the root command, perhaps at `./commands/index.js`:
147149
150+
<!-- example-region commands/index.js -->
151+
148152
```js
149153
export const name = 'pirate-parser';
150154
export const usage = 'Usage: $0 <cmd> [args]';
151155
```
152156
153157
Finally, create a subcommand, perhaps at `./commands/hello.js`:
154158
159+
<!-- example-region commands/hello.js -->
160+
155161
```js
156162
export const command = '$0 [name]';
157163

@@ -170,7 +176,9 @@ export function builder(blackFlag, helpOrVersionSet, argv) {
170176
return {
171177
attention: {
172178
boolean: true,
173-
description: 'Alert the watch that the captain is around'
179+
description: `Alert the watch${
180+
helpOrVersionSet ? ' (only available when greeting captain)' : ''
181+
}`
174182
}
175183
};
176184
}
@@ -197,10 +205,14 @@ export async function handler(argv) {
197205
198206
Then run it:
199207
208+
<!-- example-region command-1 -->
209+
200210
```shell
201211
node cli.js --help
202212
```
203213
214+
<!-- example-region output-1 -->
215+
204216
```text
205217
Usage: pirate-parser <cmd> [args]
206218

@@ -214,10 +226,14 @@ Options:
214226
215227
---
216228
229+
<!-- example-region command-2 -->
230+
217231
```shell
218232
node cli.js hello --help
219233
```
220234
235+
<!-- example-region output-2 -->
236+
221237
```text
222238
Usage: pirate-parser hello [name]
223239

@@ -228,35 +244,47 @@ Positionals:
228244

229245
Options:
230246
--help Show help text [boolean]
231-
--attention Alert the watch that the captain is around [boolean]
247+
--attention Alert the watch (only available when greeting captain) [boolean]
232248
```
233249
234250
---
235251
252+
<!-- example-region command-3 -->
253+
236254
```shell
237255
node cli.js hello Parrot
238256
```
239257
258+
<!-- example-region output-3 -->
259+
240260
```text
241261
Hello Parrot, welcome to Black Flag!
242262
```
243263
244264
---
245265
266+
<!-- example-region command-4 -->
267+
246268
```shell
247269
node cli.js hello CAPTAIN
248270
```
249271
272+
<!-- example-region output-4 -->
273+
250274
```text
251275
Hello CAPTAIN, welcome to Black Flag!
252276
```
253277
254278
---
255279
280+
<!-- example-region command-5 -->
281+
256282
```shell
257283
node cli.js hello Parrot --attention
258284
```
259285
286+
<!-- example-region output-5 -->
287+
260288
```text
261289
Usage: pirate-parser hello [name]
262290

@@ -271,10 +299,14 @@ Unknown argument: attention
271299
272300
---
273301
302+
<!-- example-region command-6 -->
303+
274304
```shell
275305
node cli.js hello CAPTAIN --attention
276306
```
277307
308+
<!-- example-region output-6 -->
309+
278310
```text
279311
-!- Captain is on the bridge -!-
280312
Hello CAPTAIN, welcome to Black Flag!

test/end-to-end/e2e-docs.test.ts

+59-77
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
// * containers, and are built to run in GitHub Actions CI pipelines; some can
99
// * also be run locally.
1010

11+
import assert from 'node:assert';
1112
import { once } from 'node:events';
1213
import { createWriteStream } from 'node:fs';
1314

1415
import { toAbsolutePath, toDirname, toPath } from '@-xun/fs';
1516
import { readJsonc, readXPackageJsonAtRoot } from '@-xun/project';
17+
import { extractExamplesFromDocument } from '@-xun/project-fs';
1618

1719
import {
1820
run as runYesRejectOnBadExit,
@@ -87,10 +89,25 @@ const sharedRunEnv: RunOptions['env'] = {
8789
DEBUG_COLORS: 'false'
8890
};
8991

90-
describe('./README', () => {
92+
function split(str: string | undefined) {
93+
assert(str);
94+
return str.split(' ').slice(2);
95+
}
96+
97+
describe('./README.md', () => {
9198
test('quick start', async () => {
9299
expect.hasAssertions();
93100

101+
const examples = await extractExamplesFromDocument(
102+
require.resolve('../../README.md'),
103+
{ useCached: true }
104+
);
105+
106+
const examplesRegExp = await extractExamplesFromDocument(
107+
require.resolve('../../README.md'),
108+
{ useCached: true, asRegExp: true }
109+
);
110+
94111
await withMockedFixture(
95112
async ({ root }) => {
96113
const run = runnerFactory('node', ['cli.js'], {
@@ -102,132 +119,97 @@ describe('./README', () => {
102119
{
103120
const { stdout, stderr, exitCode } = await run(['--version']);
104121

105-
expect({ stderr, exitCode, stdout }).toStrictEqual({
122+
expect({ id: 0, stderr, exitCode, stdout }).toStrictEqual({
123+
id: 0,
106124
stderr: '',
107125
exitCode: 0,
108126
stdout: '0.0.1'
109127
});
110128
}
111129

112130
{
113-
const { stdout, stderr, exitCode } = await run(['--help']);
131+
const { stdout, stderr, exitCode } = await run(
132+
split(examples.get('command-1'))
133+
);
114134

115-
expect({ stderr, exitCode, stdout }).toStrictEqual({
135+
expect({ id: 1, stderr, exitCode, stdout }).toStrictEqual({
136+
id: 1,
116137
stderr: '',
117138
exitCode: 0,
118-
stdout: expect.stringMatching(
119-
/Usage: pirate-parser <cmd> \[args\]\n\nCommands:\n\s+ pirate-parser hello\s+ Welcome ter black flag, a declarative wrapper around yargs!\n\nOptions:\n\s+ --help\s+ Show help text\s+ \[boolean\]\n\s+ --version\s+ Show version number\s+ \[boolean\]/
120-
)
139+
stdout: expect.stringMatching(examplesRegExp.get('output-1')!)
121140
});
122141
}
123142

124143
{
125-
const { stdout, stderr, exitCode } = await run(['hello', '--help']);
144+
const { stdout, stderr, exitCode } = await run(
145+
split(examples.get('command-2'))
146+
);
126147

127-
expect({ stderr, exitCode, stdout }).toStrictEqual({
148+
expect({ id: 2, stderr, exitCode, stdout }).toStrictEqual({
149+
id: 2,
128150
stderr: '',
129151
exitCode: 0,
130-
stdout: expect.stringMatching(
131-
/Usage: pirate-parser hello \[name\]\n\nWelcome ter black flag, a declarative wrapper around yargs!\n\nPositionals:\n\s+ name\s+ The name to say hello to\s+ \[string\] \[default: "Cambi"\]\n\nOptions:\n\s+ --help\s+ Show help text\s+ \[boolean\]/
132-
)
152+
stdout: expect.stringMatching(examplesRegExp.get('output-2')!)
133153
});
134154
}
135155

136156
{
137-
const { stdout, stderr, exitCode } = await run(['hello', 'Parrot']);
157+
const { stdout, stderr, exitCode } = await run(
158+
split(examples.get('command-3'))
159+
);
138160

139-
expect({ stderr, exitCode, stdout }).toStrictEqual({
161+
expect({ id: 3, stderr, exitCode, stdout }).toStrictEqual({
162+
id: 3,
140163
stderr: '',
141164
exitCode: 0,
142-
stdout: 'Hello Parrot, welcome to Black Flag!'
165+
stdout: expect.stringMatching(examplesRegExp.get('output-3')!)
143166
});
144167
}
145168

146169
{
147-
const { stdout, stderr, exitCode } = await run(['hello', 'CAPTAIN']);
170+
const { stdout, stderr, exitCode } = await run(
171+
split(examples.get('command-4'))
172+
);
148173

149-
expect({ stderr, exitCode, stdout }).toStrictEqual({
174+
expect({ id: 4, stderr, exitCode, stdout }).toStrictEqual({
175+
id: 4,
150176
stderr: '',
151177
exitCode: 0,
152-
stdout: 'Hello CAPTAIN, welcome to Black Flag!'
178+
stdout: expect.stringMatching(examplesRegExp.get('output-4')!)
153179
});
154180
}
155181

156182
{
157-
const { stdout, stderr, exitCode } = await run([
158-
'hello',
159-
'Parrot',
160-
'--attention'
161-
]);
183+
const { stdout, stderr, exitCode } = await run(
184+
split(examples.get('command-5'))
185+
);
162186

163-
expect({ stderr, exitCode, stdout }).toStrictEqual({
187+
expect({ id: 5, stderr, exitCode, stdout }).toStrictEqual({
188+
id: 5,
164189
stdout: '',
165190
exitCode: 1,
166-
stderr: expect.stringMatching(
167-
/Usage: pirate-parser hello \[name\]\n\nWelcome ter black flag, a declarative wrapper around yargs!\n\nPositionals:\n\s+ name\s+ The name to say hello to\s+ \[string\] \[default: "Cambi"\]\n\nOptions:\n\s+ --help\s+ Show help text\s+ \[boolean\]\n\nUnknown argument: attention/
168-
)
191+
stderr: expect.stringMatching(examplesRegExp.get('output-5')!)
169192
});
170193
}
171194

172195
{
173-
const { stdout, stderr, exitCode } = await run([
174-
'hello',
175-
'CAPTAIN',
176-
'--attention'
177-
]);
196+
const { stdout, stderr, exitCode } = await run(
197+
split(examples.get('command-6'))
198+
);
178199

179-
expect({ stderr, exitCode, stdout }).toStrictEqual({
200+
expect({ id: 6, stderr, exitCode, stdout }).toStrictEqual({
201+
id: 6,
180202
stderr: '',
181203
exitCode: 0,
182-
stdout:
183-
'-!- Captain is on the bridge -!-\nHello CAPTAIN, welcome to Black Flag!'
204+
stdout: expect.stringMatching(examplesRegExp.get('output-6')!)
184205
});
185206
}
186207
},
187208
{
188209
initialVirtualFiles: {
189-
'cli.js': /* js */ `#!/usr/bin/env node
190-
191-
import { runProgram } from '@black-flag/core';
192-
export default runProgram(import.meta.resolve('./commands'));
193-
`,
194-
'commands/index.js': /* js */ `export const name = 'pirate-parser';
195-
export const usage = 'Usage: $0 <cmd> [args]';
196-
`,
197-
'commands/hello.js':
198-
/* js */ `export const command = '$0 [name]';
199-
200-
export const description =
201-
'Welcome ter black flag, a declarative wrapper around yargs!';
202-
203-
export function builder(blackFlag, helpOrVersionSet, argv) {
204-
blackFlag.positional('name', {
205-
type: 'string',
206-
default: 'Cambi',
207-
describe: 'The name to say hello to'
208-
});
209-
210-
// A special --attention flag only available when greeting the captain!
211-
if (helpOrVersionSet || argv?.name === 'CAPTAIN') {
212-
return {
213-
attention: {
214-
boolean: true,
215-
description: 'Alert the watch that the captain is around'
216-
}
217-
};
218-
}
219-
}
220-
221-
export async function handler(argv) {
222-
if (argv.attention) {
223-
console.log('-!- Captain is on the bridge -!-');
224-
}
225-
226-
console.log(` +
227-
'`Hello ${argv.name}, welcome to Black Flag!`' +
228-
`);
229-
}
230-
`
210+
'cli.js': examples.get('cli.js'),
211+
'commands/index.js': examples.get('commands/index.js'),
212+
'commands/hello.js': examples.get('commands/hello.js')
231213
}
232214
}
233215
);

0 commit comments

Comments
 (0)