Skip to content

Commit a39bd6a

Browse files
authored
chore: refactor windows shim tests (#6576)
1 parent 939a188 commit a39bd6a

File tree

1 file changed

+70
-89
lines changed

1 file changed

+70
-89
lines changed

test/bin/windows-shims.js

Lines changed: 70 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
const t = require('tap')
22
const spawn = require('@npmcli/promise-spawn')
33
const { spawnSync } = require('child_process')
4-
const { resolve } = require('path')
4+
const { resolve, join } = require('path')
55
const { readFileSync, chmodSync } = require('fs')
66
const Diff = require('diff')
77
const { 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

1213
t.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

4041
t.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

Comments
 (0)