@@ -20,6 +20,9 @@ const BIN = join(ROOT, 'bin')
2020const SHIMS = readNonJsFiles ( BIN )
2121const NODE_GYP = readNonJsFiles ( join ( BIN , 'node-gyp-bin' ) )
2222const SHIM_EXTS = [ ...new Set ( Object . keys ( SHIMS ) . map ( p => extname ( p ) ) ) ]
23+ const PACKAGE_NAME = 'test'
24+ const PACKAGE_VERSION = '1.0.0'
25+ const SCRIPT_NAME = 'args.js'
2326
2427t . test ( 'shim contents' , t => {
2528 // these scripts should be kept in sync so this tests the contents of each
@@ -99,6 +102,18 @@ t.test('run shims', t => {
99102 } ,
100103 } ,
101104 } ,
105+ // test script returning all command line arguments
106+ [ SCRIPT_NAME ] : `#!/usr/bin/env node\n\nprocess.argv.slice(2).forEach((arg) => console.log(arg))` ,
107+ // package.json for the test script
108+ 'package.json' : `
109+ {
110+ "name": "${ PACKAGE_NAME } ",
111+ "version": "${ PACKAGE_VERSION } ",
112+ "scripts": {
113+ "test": "node ${ SCRIPT_NAME } "
114+ },
115+ "bin": "${ SCRIPT_NAME } "
116+ }` ,
102117 } )
103118
104119 // The removal of this fixture causes this test to fail when done with
@@ -112,6 +127,12 @@ t.test('run shims', t => {
112127 // only cygwin *requires* the -l, but the others are ok with it
113128 args . unshift ( '-l' )
114129 }
130+ if ( cmd . toLowerCase ( ) . endsWith ( 'powershell.exe' ) || cmd . toLowerCase ( ) . endsWith ( 'pwsh.exe' ) ) {
131+ // pwsh *requires* the -Command, Windows PowerShell defaults to it
132+ args . unshift ( '-Command' )
133+ // powershell requires escaping double-quotes for this test
134+ args = args . map ( elem => elem . replaceAll ( '"' , '\\"' ) )
135+ }
115136 const result = spawnSync ( `"${ cmd } "` , args , {
116137 // don't hit the registry for the update check
117138 env : { PATH : path , npm_config_update_notifier : 'false' } ,
@@ -162,6 +183,7 @@ t.test('run shims', t => {
162183
163184 const shells = Object . entries ( {
164185 cmd : 'cmd' ,
186+ powershell : 'powershell' ,
165187 pwsh : 'pwsh' ,
166188 git : join ( ProgramFiles , 'Git' , 'bin' , 'bash.exe' ) ,
167189 'user git' : join ( ProgramFiles , 'Git' , 'usr' , 'bin' , 'bash.exe' ) ,
@@ -216,7 +238,7 @@ t.test('run shims', t => {
216238 }
217239 } )
218240
219- const matchCmd = ( t , cmd , bin , match ) => {
241+ const matchCmd = ( t , cmd , bin , match , params , expected ) => {
220242 const args = [ ]
221243 const opts = { }
222244
@@ -227,25 +249,40 @@ t.test('run shims', t => {
227249 case 'bash.exe' :
228250 args . push ( bin )
229251 break
252+ case 'powershell.exe' :
230253 case 'pwsh.exe' :
231254 args . push ( `${ bin } .ps1` )
232255 break
233256 default :
234257 throw new Error ( 'unknown shell' )
235258 }
236259
237- const isNpm = bin === 'npm'
238- const result = spawnPath ( cmd , [ ...args , isNpm ? 'help' : '--version' ] , opts )
260+ const result = spawnPath ( cmd , [ ...args , ...params ] , opts )
261+
262+ // skip the first 3 lines of "npm test" to get the actual script output
263+ if ( params [ 0 ] . startsWith ( 'test' ) ) {
264+ result . stdout = result . stdout ?. toString ( ) . split ( '\n' ) . slice ( 3 ) . join ( '\n' ) . trim ( )
265+ }
239266
240267 t . match ( result , {
241268 status : 0 ,
242269 signal : null ,
243270 stderr : '' ,
244- stdout : isNpm ? `npm@ ${ version } ${ ROOT } ` : version ,
271+ stdout : expected ,
245272 ...match ,
246- } , `${ cmd } ${ bin } ` )
273+ } , `${ cmd } ${ bin } ${ params [ 0 ] } ` )
247274 }
248275
276+ // Array with command line parameters and expected output
277+ const tests = [
278+ { bin : 'npm' , params : [ 'help' ] , expected : `npm@${ version } ${ ROOT } ` } ,
279+ { bin : 'npx' , params : [ '--version' ] , expected : version } ,
280+ { bin : 'npm' , params : [ 'test' ] , expected : '' } ,
281+ { bin : 'npm' , params : [ `test -- hello -p1 world -p2 "hello world" --q1=hello world --q2="hello world"` ] , expected : `hello\n-p1\nworld\n-p2\nhello world\n--q1=hello\nworld\n--q2=hello world` } ,
282+ { bin : 'npm' , params : [ 'test -- a=1,b=2,c=3' ] , expected : `a=1,b=2,c=3` } ,
283+ { bin : 'npx' , params : [ '. -- a=1,b=2,c=3' ] , expected : `a=1,b=2,c=3` } ,
284+ ]
285+
249286 // ensure that all tests are either run or skipped
250287 t . plan ( shells . length )
251288
@@ -259,9 +296,17 @@ t.test('run shims', t => {
259296 }
260297 return t . end ( )
261298 }
262- t . plan ( 2 )
263- matchCmd ( t , cmd , 'npm' , match )
264- matchCmd ( t , cmd , 'npx' , match )
299+ t . plan ( tests . length )
300+ for ( const { bin, params, expected } of tests ) {
301+ if ( name === 'cygwin bash' && (
302+ ( bin === 'npm' && params [ 0 ] . startsWith ( 'test' ) ) ||
303+ ( bin === 'npx' && params [ 0 ] . startsWith ( '.' ) )
304+ ) ) {
305+ t . skip ( "`cygwin bash` doesn't respect option `{ cwd: path }` when calling `spawnSync`" )
306+ } else {
307+ matchCmd ( t , cmd , bin , match , params , expected )
308+ }
309+ }
265310 } )
266311 }
267312} )
0 commit comments