1
1
const t = require ( 'tap' )
2
+ const spawn = require ( '@npmcli/promise-spawn' )
3
+ const { spawnSync } = require ( 'child_process' )
4
+ const { resolve } = require ( 'path' )
5
+ const { readFileSync, chmodSync } = require ( 'fs' )
6
+ const Diff = require ( 'diff' )
7
+ const { version } = require ( '../../package.json' )
2
8
3
- if ( process . platform !== 'win32' ) {
4
- t . plan ( 0 , 'test only relevant on windows' )
5
- process . exit ( 0 )
6
- }
9
+ const npmShim = resolve ( __dirname , '../../bin/npm' )
10
+ const npxShim = resolve ( __dirname , '../../bin/npx' )
7
11
8
12
const has = path => {
9
13
try {
@@ -24,110 +28,137 @@ const has = path => {
24
28
}
25
29
}
26
30
27
- const { version } = require ( '../../package.json' )
28
- const spawn = require ( '@npmcli/promise-spawn' )
29
- const { spawnSync } = require ( 'child_process' )
30
- const { resolve } = require ( 'path' )
31
- const { ProgramFiles, SystemRoot } = process . env
32
- const { readFileSync, chmodSync } = require ( 'fs' )
33
- const gitBash = resolve ( ProgramFiles , 'Git' , 'bin' , 'bash.exe' )
34
- const gitUsrBinBash = resolve ( ProgramFiles , 'Git' , 'usr' , 'bin' , 'bash.exe' )
35
- const wslBash = resolve ( SystemRoot , 'System32' , 'bash.exe' )
36
- const cygwinBash = resolve ( SystemRoot , '/' , 'cygwin64' , 'bin' , 'bash.exe' )
37
-
38
- const bashes = Object . entries ( {
39
- 'wsl bash' : wslBash ,
40
- 'git bash' : gitBash ,
41
- 'git internal bash' : gitUsrBinBash ,
42
- 'cygwin bash' : cygwinBash ,
31
+ t . test ( 'npm vs npx' , t => {
32
+ // these scripts should be kept in sync so this tests the contents of each
33
+ // and does a diff to ensure the only differences between them are necessary
34
+ const diffFiles = ( ext = '' ) => Diff . diffChars (
35
+ readFileSync ( `${ npmShim } ${ ext } ` , 'utf8' ) ,
36
+ readFileSync ( `${ npxShim } ${ ext } ` , 'utf8' )
37
+ ) . filter ( v => v . added || v . removed ) . map ( ( v , i ) => i === 0 ? v . value : v . value . toUpperCase ( ) )
38
+
39
+ t . test ( 'bash' , t => {
40
+ const [ npxCli , ...changes ] = diffFiles ( )
41
+ const npxCliLine = npxCli . split ( '\n' ) . reverse ( ) . join ( '' )
42
+ t . match ( npxCliLine , / ^ N P X _ C L I _ J S = / , 'has NPX_CLI' )
43
+ t . equal ( changes . length , 20 )
44
+ t . strictSame ( [ ...new Set ( changes ) ] , [ 'M' , 'X' ] , 'all other changes are m->x' )
45
+ t . end ( )
46
+ } )
47
+
48
+ t . test ( 'cmd' , t => {
49
+ const [ npxCli , ...changes ] = diffFiles ( '.cmd' )
50
+ t . match ( npxCli , / ^ S E T " N P X _ C L I _ J S = / , 'has NPX_CLI' )
51
+ t . equal ( changes . length , 12 )
52
+ t . strictSame ( [ ...new Set ( changes ) ] , [ 'M' , 'X' ] , 'all other changes are m->x' )
53
+ t . end ( )
54
+ } )
55
+
56
+ t . end ( )
43
57
} )
44
58
45
- const npmShim = resolve ( __dirname , '../../bin/npm' )
46
- const npxShim = resolve ( __dirname , '../../bin/npx' )
59
+ t . test ( 'basic' , t => {
60
+ if ( process . platform !== 'win32' ) {
61
+ t . plan ( 0 , 'test only relevant on windows' )
62
+ return
63
+ }
47
64
48
- const path = t . testdir ( {
49
- 'node.exe' : readFileSync ( process . execPath ) ,
50
- npm : readFileSync ( npmShim ) ,
51
- npx : readFileSync ( npxShim ) ,
52
- // simulate the state where one version of npm is installed
53
- // with node, but we should load the globally installed one
54
- 'global-prefix' : {
55
- node_modules : {
56
- npm : t . fixture ( 'symlink' , resolve ( __dirname , '../..' ) ) ,
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
+
78
+ const path = t . testdir ( {
79
+ 'node.exe' : readFileSync ( process . execPath ) ,
80
+ npm : readFileSync ( npmShim ) ,
81
+ npx : readFileSync ( npxShim ) ,
82
+ // simulate the state where one version of npm is installed
83
+ // with node, but we should load the globally installed one
84
+ 'global-prefix' : {
85
+ node_modules : {
86
+ npm : t . fixture ( 'symlink' , resolve ( __dirname , '../..' ) ) ,
87
+ } ,
57
88
} ,
58
- } ,
59
- // put in a shim that ONLY prints the intended global prefix,
60
- // and should not be used for anything else.
61
- node_modules : {
62
- npm : {
63
- bin : {
64
- 'npx-cli.js' : `
89
+ // put in a shim that ONLY prints the intended global prefix,
90
+ // and should not be used for anything else.
91
+ node_modules : {
92
+ npm : {
93
+ bin : {
94
+ 'npx-cli.js' : `
65
95
throw new Error('this should not be called')
66
96
` ,
67
- 'npm-cli.js' : `
97
+ 'npm-cli.js' : `
68
98
const assert = require('assert')
69
99
const args = process.argv.slice(2)
70
100
assert.equal(args[0], 'prefix')
71
101
assert.equal(args[1], '-g')
72
102
const { resolve } = require('path')
73
103
console.log(resolve(__dirname, '../../../global-prefix'))
74
104
` ,
105
+ } ,
75
106
} ,
76
107
} ,
77
- } ,
78
- } )
79
- chmodSync ( resolve ( path , 'npm' ) , 0o755 )
80
- chmodSync ( resolve ( path , 'npx' ) , 0o755 )
108
+ } )
109
+ chmodSync ( resolve ( path , 'npm' ) , 0o755 )
110
+ chmodSync ( resolve ( path , 'npx' ) , 0o755 )
81
111
82
- for ( const [ name , bash ] of bashes ) {
83
- if ( ! has ( bash ) ) {
84
- t . skip ( `${ name } not installed` , { bin : bash , diagnostic : true } )
85
- continue
86
- }
112
+ for ( const [ name , bash ] of bashes ) {
113
+ if ( ! has ( bash ) ) {
114
+ t . skip ( `${ name } not installed` , { bin : bash , diagnostic : true } )
115
+ continue
116
+ }
87
117
88
- if ( bash === cygwinBash && process . env . NYC_CONFIG ) {
89
- t . skip ( 'Cygwin does not play nicely with NYC, run without coverage' )
90
- continue
91
- }
118
+ if ( bash === cygwinBash && process . env . NYC_CONFIG ) {
119
+ t . skip ( 'Cygwin does not play nicely with NYC, run without coverage' )
120
+ continue
121
+ }
92
122
93
- t . test ( name , async t => {
94
- t . plan ( 2 )
95
- t . test ( 'npm' , async t => {
123
+ t . test ( name , async t => {
124
+ t . plan ( 2 )
125
+ t . test ( 'npm' , async t => {
96
126
// only cygwin *requires* the -l, but the others are ok with it
97
127
// don't hit the registry for the update check
98
- const args = [ '-l' , 'npm' , 'help' ]
128
+ const args = [ '-l' , 'npm' , 'help' ]
99
129
100
- const result = await spawn ( bash , args , {
101
- env : { PATH : path , npm_config_update_notifier : 'false' } ,
102
- cwd : path ,
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
+ } )
103
143
} )
104
- t . match ( result , {
105
- cmd : bash ,
106
- args : [ '-l' , 'npm' , 'help' ] ,
107
- code : 0 ,
108
- signal : null ,
109
- stderr : String ,
110
- // should have loaded this instance of npm we symlinked in
111
- stdout : `npm@${ version } ${ resolve ( __dirname , '../..' ) } ` ,
112
- } )
113
- } )
114
144
115
- t . test ( 'npx' , async t => {
116
- const args = [ '-l' , 'npx' , '--version' ]
145
+ t . test ( 'npx' , async t => {
146
+ const args = [ '-l' , 'npx' , '--version' ]
117
147
118
- const result = await spawn ( bash , args , {
119
- env : { PATH : path , npm_config_update_notifier : 'false' } ,
120
- cwd : path ,
121
- } )
122
- t . match ( result , {
123
- cmd : bash ,
124
- args : [ '-l' , 'npx' , '--version' ] ,
125
- code : 0 ,
126
- signal : null ,
127
- stderr : String ,
128
- // should have loaded this instance of npm we symlinked in
129
- stdout : version ,
148
+ const result = await spawn ( bash , args , {
149
+ env : { PATH : path , npm_config_update_notifier : 'false' } ,
150
+ cwd : path ,
151
+ } )
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
+ } )
130
161
} )
131
162
} )
132
- } )
133
- }
163
+ }
164
+ } )
0 commit comments