diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/bin/windows-shims.js | 135 | ||||
-rw-r--r-- | test/coverage-map.js | 4 | ||||
-rw-r--r-- | test/lib/doctor.js | 2 | ||||
-rw-r--r-- | test/lib/npm.js | 13 |
4 files changed, 145 insertions, 9 deletions
diff --git a/test/bin/windows-shims.js b/test/bin/windows-shims.js new file mode 100644 index 000000000..8d73e39f2 --- /dev/null +++ b/test/bin/windows-shims.js @@ -0,0 +1,135 @@ +const t = require('tap') + +if (process.platform !== 'win32') { + t.plan(0, 'test only relevant on windows') + process.exit(0) +} + +const has = path => { + try { + // If WSL is installed, it *has* a bash.exe, but it fails if + // there is no distro installed, so we need to detect that. + const result = spawnSync(path, ['-l', '-c', 'exit 0']) + if (result.status === 0) + return true + else { + // print whatever error we got + throw result.error || Object.assign(new Error(String(result.stderr)), { + code: result.status, + }) + } + } catch (er) { + t.comment(`not installed: ${path}`, er) + return false + } +} + +const { version } = require('../../package.json') +const spawn = require('@npmcli/promise-spawn') +const { spawnSync } = require('child_process') +const { resolve } = require('path') +const { ProgramFiles, SystemRoot } = process.env +const { readFileSync, chmodSync } = require('fs') +const gitBash = resolve(ProgramFiles, 'Git', 'bin', 'bash.exe') +const gitUsrBinBash = resolve(ProgramFiles, 'Git', 'usr', 'bin', 'bash.exe') +const wslBash = resolve(SystemRoot, 'System32', 'bash.exe') +const cygwinBash = resolve(SystemRoot, '/', 'cygwin64', 'bin', 'bash.exe') + +const bashes = Object.entries({ + 'wsl bash': wslBash, + 'git bash': gitBash, + 'git internal bash': gitUsrBinBash, + 'cygwin bash': cygwinBash, +}) + +const npmShim = resolve(__dirname, '../../bin/npm') +const npxShim = resolve(__dirname, '../../bin/npx') + +const path = t.testdir({ + 'node.exe': readFileSync(process.execPath), + npm: readFileSync(npmShim), + npx: readFileSync(npxShim), + // simulate the state where one version of npm is installed + // with node, but we should load the globally installed one + 'global-prefix': { + node_modules: { + npm: t.fixture('symlink', resolve(__dirname, '../..')), + }, + }, + // put in a shim that ONLY prints the intended global prefix, + // and should not be used for anything else. + node_modules: { + npm: { + bin: { + 'npx-cli.js': ` + throw new Error('this should not be called') + `, + 'npm-cli.js': ` + const assert = require('assert') + const args = process.argv.slice(2) + assert.equal(args[0], 'prefix') + assert.equal(args[1], '-g') + const { resolve } = require('path') + console.log(resolve(__dirname, '../../../global-prefix')) + `, + }, + }, + }, +}) +chmodSync(resolve(path, 'npm'), 0o755) +chmodSync(resolve(path, 'npx'), 0o755) + +for (const [name, bash] of bashes) { + if (!has(bash)) { + t.skip(`${name} not installed`, { bin: bash, diagnostic: true }) + continue + } + + if (bash === cygwinBash && process.env.NYC_CONFIG) { + t.skip('Cygwin does not play nicely with NYC, run without coverage') + continue + } + + t.test(name, async t => { + t.plan(2) + t.test('npm', async t => { + // only cygwin *requires* the -l, but the others are ok with it + // don't hit the registry for the update check + const args = ['-l', 'npm', 'help'] + + const result = await spawn(bash, args, { + env: { PATH: path, npm_config_update_notifier: 'false' }, + cwd: path, + stdioString: true, + }) + t.match(result, { + cmd: bash, + args: ['-l', 'npm', 'help'], + code: 0, + signal: null, + stderr: String, + // should have loaded this instance of npm we symlinked in + stdout: `npm@${version} ${resolve(__dirname, '../..')}`, + }) + }) + + t.test('npx', async t => { + const args = ['-l', 'npx', '--version'] + + const result = await spawn(bash, args, { + env: { PATH: path, npm_config_update_notifier: 'false' }, + cwd: path, + stdioString: true, + }) + t.match(result, { + cmd: bash, + args: ['-l', 'npx', '--version'], + code: 0, + signal: null, + stderr: String, + // should have loaded this instance of npm we symlinked in + stdout: version, + }) + }) + }) +} diff --git a/test/coverage-map.js b/test/coverage-map.js index f247c051f..63f2a608e 100644 --- a/test/coverage-map.js +++ b/test/coverage-map.js @@ -7,6 +7,10 @@ const coverageMap = (filename) => { return glob.sync(`${dir}/**/*.js`) .map(f => relative(process.cwd(), f)) } + if (/windows-shims\.js$/.test(filename)) { + // this one doesn't provide any coverage nyc can track + return [] + } if (/^test\/(lib|bin)\//.test(filename)) return filename.replace(/^test\//, '') return [] diff --git a/test/lib/doctor.js b/test/lib/doctor.js index 820049347..eaa7ad72d 100644 --- a/test/lib/doctor.js +++ b/test/lib/doctor.js @@ -487,7 +487,7 @@ test('node versions', t => { const dir = st.testdir({ cache: { one: 'one', - link: st.fixture('symlink', './one'), + link: st.fixture('symlink', './baddir'), unreadable: 'unreadable', baddir: {}, }, diff --git a/test/lib/npm.js b/test/lib/npm.js index 18bed36de..1f7a54e22 100644 --- a/test/lib/npm.js +++ b/test/lib/npm.js @@ -1,5 +1,4 @@ const t = require('tap') -const fs = require('fs') // delete this so that we don't have configs from the fact that it // is being run by 'npm test' @@ -21,7 +20,7 @@ for (const env of Object.keys(process.env).filter(e => /^npm_/.test(e))) { delete process.env[env] } -const { resolve } = require('path') +const { resolve, dirname } = require('path') const actualPlatform = process.platform @@ -249,13 +248,11 @@ t.test('npm.load', t => { const node = actualPlatform === 'win32' ? 'node.exe' : 'node' const dir = t.testdir({ '.npmrc': 'foo = bar', + bin: t.fixture('symlink', dirname(process.execPath)), }) - // create manually to set the 'file' option in windows - fs.symlinkSync(process.execPath, resolve(dir, node), 'file') - const PATH = process.env.PATH || process.env.Path - process.env.PATH = dir + process.env.PATH = resolve(dir, 'bin') const { execPath, argv: processArgv } = process process.argv = [ node, @@ -294,7 +291,7 @@ t.test('npm.load', t => { [ 'verbose', 'node symlink', - resolve(dir, node), + resolve(dir, 'bin', node), ], [ 'timing', @@ -303,7 +300,7 @@ t.test('npm.load', t => { ], ]) logs.length = 0 - t.equal(process.execPath, resolve(dir, node)) + t.equal(process.execPath, resolve(dir, 'bin', node)) }) await npm.commands.ll([], (er) => { |