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' ;
1112import { once } from 'node:events' ;
1213import { createWriteStream } from 'node:fs' ;
1314
1415import { toAbsolutePath , toDirname , toPath } from '@-xun/fs' ;
1516import { readJsonc , readXPackageJsonAtRoot } from '@-xun/project' ;
17+ import { extractExamplesFromDocument } from '@-xun/project-fs' ;
1618
1719import {
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- / U s a g e : p i r a t e - p a r s e r < c m d > \[ a r g s \] \n \n C o m m a n d s : \n \s + p i r a t e - p a r s e r h e l l o \s + W e l c o m e t e r b l a c k f l a g , a d e c l a r a t i v e w r a p p e r a r o u n d y a r g s ! \n \n O p t i o n s : \n \s + - - h e l p \s + S h o w h e l p t e x t \s + \[ b o o l e a n \] \n \s + - - v e r s i o n \s + S h o w v e r s i o n n u m b e r \s + \[ b o o l e a n \] /
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- / U s a g e : p i r a t e - p a r s e r h e l l o \[ n a m e \] \n \n W e l c o m e t e r b l a c k f l a g , a d e c l a r a t i v e w r a p p e r a r o u n d y a r g s ! \n \n P o s i t i o n a l s : \n \s + n a m e \s + T h e n a m e t o s a y h e l l o t o \s + \[ s t r i n g \] \[ d e f a u l t : " C a m b i " \] \n \n O p t i o n s : \n \s + - - h e l p \s + S h o w h e l p t e x t \s + \[ b o o l e a n \] /
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- / U s a g e : p i r a t e - p a r s e r h e l l o \[ n a m e \] \n \n W e l c o m e t e r b l a c k f l a g , a d e c l a r a t i v e w r a p p e r a r o u n d y a r g s ! \n \n P o s i t i o n a l s : \n \s + n a m e \s + T h e n a m e t o s a y h e l l o t o \s + \[ s t r i n g \] \[ d e f a u l t : " C a m b i " \] \n \n O p t i o n s : \n \s + - - h e l p \s + S h o w h e l p t e x t \s + \[ b o o l e a n \] \n \n U n k n o w n a r g u m e n t : a t t e n t i o n /
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