11const t = require ( 'tap' )
22const spawn = require ( '@npmcli/promise-spawn' )
33const { spawnSync } = require ( 'child_process' )
4- const { resolve } = require ( 'path' )
4+ const { resolve, join } = require ( 'path' )
55const { readFileSync, chmodSync } = require ( 'fs' )
66const Diff = require ( 'diff' )
77const { version } = require ( '../../package.json' )
88
9- const npmShim = resolve ( __dirname , '../../bin/npm' )
10- const npxShim = resolve ( __dirname , '../../bin/npx' )
9+ const root = resolve ( __dirname , '../..' )
10+ const npmShim = join ( root , 'bin/npm' )
11+ const npxShim = join ( root , 'bin/npx' )
1112
1213t . test ( 'npm vs npx' , t => {
1314 // these scripts should be kept in sync so this tests the contents of each
@@ -39,42 +40,10 @@ t.test('npm vs npx', t => {
3940
4041t . test ( 'basic' , async t => {
4142 if ( process . platform !== 'win32' ) {
42- t . plan ( 0 , 'test only relevant on windows' )
43+ t . comment ( 'test only relevant on windows' )
4344 return
4445 }
4546
46- const has = path => {
47- try {
48- // If WSL is installed, it *has* a bash.exe, but it fails if
49- // there is no distro installed, so we need to detect that.
50- const result = spawnSync ( path , [ '-l' , '-c' , 'exit 0' ] )
51- if ( result . status === 0 ) {
52- return true
53- } else {
54- // print whatever error we got
55- throw result . error || Object . assign ( new Error ( String ( result . stderr ) ) , {
56- code : result . status ,
57- } )
58- }
59- } catch ( er ) {
60- t . comment ( `not installed: ${ path } ` , er )
61- return false
62- }
63- }
64-
65- const { ProgramFiles, SystemRoot } = process . env
66- const gitBash = resolve ( ProgramFiles , 'Git' , 'bin' , 'bash.exe' )
67- const gitUsrBinBash = resolve ( ProgramFiles , 'Git' , 'usr' , 'bin' , 'bash.exe' )
68- const wslBash = resolve ( SystemRoot , 'System32' , 'bash.exe' )
69- const cygwinBash = resolve ( SystemRoot , '/' , 'cygwin64' , 'bin' , 'bash.exe' )
70-
71- const bashes = Object . entries ( {
72- 'wsl bash' : wslBash ,
73- 'git bash' : gitBash ,
74- 'git internal bash' : gitUsrBinBash ,
75- 'cygwin bash' : cygwinBash ,
76- } )
77-
7847 const path = t . testdir ( {
7948 'node.exe' : readFileSync ( process . execPath ) ,
8049 npm : readFileSync ( npmShim ) ,
@@ -83,7 +52,7 @@ t.test('basic', async t => {
8352 // with node, but we should load the globally installed one
8453 'global-prefix' : {
8554 node_modules : {
86- npm : t . fixture ( 'symlink' , resolve ( __dirname , '../..' ) ) ,
55+ npm : t . fixture ( 'symlink' , root ) ,
8756 } ,
8857 } ,
8958 // put in a shim that ONLY prints the intended global prefix,
@@ -92,73 +61,85 @@ t.test('basic', async t => {
9261 npm : {
9362 bin : {
9463 'npx-cli.js' : `
95- throw new Error('this should not be called')
96- ` ,
64+ throw new Error('this should not be called')
65+ ` ,
9766 'npm-cli.js' : `
98- const assert = require('assert')
99- const args = process.argv.slice(2)
100- assert.equal(args[0], 'prefix')
101- assert.equal(args[1], '-g')
102- const { resolve } = require('path')
103- console.log(resolve(__dirname, '../../../global-prefix'))
104- ` ,
67+ const assert = require('assert')
68+ const args = process.argv.slice(2)
69+ assert.equal(args[0], 'prefix')
70+ assert.equal(args[1], '-g')
71+ const { resolve } = require('path')
72+ console.log(resolve(__dirname, '../../../global-prefix'))
73+ ` ,
10574 } ,
10675 } ,
10776 } ,
10877 } )
109- chmodSync ( resolve ( path , 'npm' ) , 0o755 )
110- chmodSync ( resolve ( path , 'npx' ) , 0o755 )
11178
112- for ( const [ name , bash ] of bashes ) {
113- if ( ! has ( bash ) ) {
114- t . skip ( `${ name } not installed` , { bin : bash , diagnostic : true } )
115- continue
79+ chmodSync ( join ( path , 'npm' ) , 0o755 )
80+ chmodSync ( join ( path , 'npx' ) , 0o755 )
81+
82+ const { ProgramFiles, SystemRoot, NYC_CONFIG } = process . env
83+ const gitBash = join ( ProgramFiles , 'Git' , 'bin' , 'bash.exe' )
84+ const gitUsrBinBash = join ( ProgramFiles , 'Git' , 'usr' , 'bin' , 'bash.exe' )
85+ const wslBash = join ( SystemRoot , 'System32' , 'bash.exe' )
86+ const cygwinBash = join ( SystemRoot , '/' , 'cygwin64' , 'bin' , 'bash.exe' )
87+
88+ const bashes = Object . entries ( {
89+ 'wsl bash' : wslBash ,
90+ 'git bash' : gitBash ,
91+ 'git internal bash' : gitUsrBinBash ,
92+ 'cygwin bash' : cygwinBash ,
93+ } ) . map ( ( [ name , bash ] ) => {
94+ let skip
95+ if ( bash === cygwinBash && NYC_CONFIG ) {
96+ skip = 'does not play nicely with NYC, run without coverage'
97+ } else {
98+ try {
99+ // If WSL is installed, it *has* a bash.exe, but it fails if
100+ // there is no distro installed, so we need to detect that.
101+ if ( spawnSync ( bash , [ '-l' , '-c' , 'exit 0' ] ) . status !== 0 ) {
102+ throw new Error ( 'not installed' )
103+ }
104+ } catch {
105+ skip = 'not installed'
106+ }
116107 }
108+ return { name, bash, skip }
109+ } )
117110
118- if ( bash === cygwinBash && process . env . NYC_CONFIG ) {
119- t . skip ( 'Cygwin does not play nicely with NYC, run without coverage' )
111+ for ( const { name, bash, skip } of bashes ) {
112+ if ( skip ) {
113+ t . skip ( name , { diagnostic : true , bin : bash , reason : skip } )
120114 continue
121115 }
122116
123117 await t . test ( name , async t => {
124- t . plan ( 2 )
125- t . test ( 'npm' , async t => {
126- // only cygwin *requires* the -l, but the others are ok with it
127- // don't hit the registry for the update check
128- const args = [ '-l' , 'npm' , 'help' ]
129-
130- const result = await spawn ( bash , args , {
131- env : { PATH : path , npm_config_update_notifier : 'false' } ,
132- cwd : path ,
133- } )
134- t . match ( result , {
135- cmd : bash ,
136- args : [ '-l' , 'npm' , 'help' ] ,
137- code : 0 ,
138- signal : null ,
139- stderr : String ,
140- // should have loaded this instance of npm we symlinked in
141- stdout : `npm@${ version } ${ resolve ( __dirname , '../..' ) } ` ,
142- } )
118+ const bins = Object . entries ( {
119+ // should have loaded this instance of npm we symlinked in
120+ npm : [ [ 'help' ] , `npm@${ version } ${ root } ` ] ,
121+ npx : [ [ '--version' ] , version ] ,
143122 } )
144123
145- t . test ( 'npx' , async t => {
146- const args = [ '-l' , 'npx' , '--version' ]
147-
148- const result = await spawn ( bash , args , {
149- env : { PATH : path , npm_config_update_notifier : 'false' } ,
150- cwd : path ,
124+ for ( const [ binName , [ cmdArgs , stdout ] ] of bins ) {
125+ await t . test ( binName , async t => {
126+ // only cygwin *requires* the -l, but the others are ok with it
127+ const args = [ '-l' , binName , ...cmdArgs ]
128+ const result = await spawn ( bash , args , {
129+ // don't hit the registry for the update check
130+ env : { PATH : path , npm_config_update_notifier : 'false' } ,
131+ cwd : path ,
132+ } )
133+ t . match ( result , {
134+ cmd : bash ,
135+ args : args ,
136+ code : 0 ,
137+ signal : null ,
138+ stderr : String ,
139+ stdout,
140+ } )
151141 } )
152- t . match ( result , {
153- cmd : bash ,
154- args : [ '-l' , 'npx' , '--version' ] ,
155- code : 0 ,
156- signal : null ,
157- stderr : String ,
158- // should have loaded this instance of npm we symlinked in
159- stdout : version ,
160- } )
161- } )
142+ }
162143 } )
163144 }
164145} )
0 commit comments