diff options
author | Ruy Adorno <ruyadorno@hotmail.com> | 2021-03-04 17:40:28 -0500 |
---|---|---|
committer | Ruy Adorno <ruyadorno@hotmail.com> | 2021-03-05 15:32:56 -0500 |
commit | f3d3769f9f6da29fb562f25074cda6c86a0366df (patch) | |
tree | 4a233305c3fcb06212a83a080f2ac988dbd3a6b9 /deps/npm/test | |
parent | 54bb7e3bff819431af1e860daf46844859e002c0 (diff) | |
download | node-new-f3d3769f9f6da29fb562f25074cda6c86a0366df.tar.gz |
deps: upgrade npm to 7.6.1
PR-URL: https://github.com/nodejs/node/pull/37606
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Diffstat (limited to 'deps/npm/test')
85 files changed, 2965 insertions, 2482 deletions
diff --git a/deps/npm/test/bin/windows-shims.js b/deps/npm/test/bin/windows-shims.js new file mode 100644 index 0000000000..8d73e39f2c --- /dev/null +++ b/deps/npm/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/deps/npm/test/coverage-map.js b/deps/npm/test/coverage-map.js index f247c051f0..63f2a608e0 100644 --- a/deps/npm/test/coverage-map.js +++ b/deps/npm/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/deps/npm/test/lib/access.js b/deps/npm/test/lib/access.js index fb799f2df2..3a732ad0aa 100644 --- a/deps/npm/test/lib/access.js +++ b/deps/npm/test/lib/access.js @@ -1,17 +1,12 @@ const { test } = require('tap') const requireInject = require('require-inject') -const access = requireInject('../../lib/access.js', { - '../../lib/npm.js': { - flatOptions: {}, - }, -}) +const Access = require('../../lib/access.js') test('completion', t => { - const { completion } = access - + const access = new Access({ flatOptions: {} }) const testComp = (argv, expect) => { - const res = completion({conf: {argv: {remain: argv}}}) + const res = access.completion({conf: {argv: {remain: argv}}}) t.resolves(res, expect, argv.join(' ')) } @@ -32,7 +27,7 @@ test('completion', t => { testComp(['npm', 'access', 'revoke'], []) t.rejects( - completion({conf: {argv: {remain: ['npm', 'access', 'foobar']}}}), + access.completion({conf: {argv: {remain: ['npm', 'access', 'foobar']}}}), { message: 'foobar not recognized' } ) @@ -40,14 +35,16 @@ test('completion', t => { }) test('subcommand required', t => { - access([], (err) => { + const access = new Access({ flatOptions: {} }) + access.exec([], (err) => { t.equal(err, '\nUsage: Subcommand is required.\n\n' + access.usage) t.end() }) }) test('unrecognized subcommand', (t) => { - access(['blerg'], (err) => { + const access = new Access({ flatOptions: {} }) + access.exec(['blerg'], (err) => { t.match( err, /Usage: blerg is not a recognized subcommand/, @@ -58,7 +55,8 @@ test('unrecognized subcommand', (t) => { }) test('edit', (t) => { - access([ + const access = new Access({ flatOptions: {} }) + access.exec([ 'edit', '@scoped/another', ], (err) => { @@ -77,10 +75,8 @@ test('access public on unscoped package', (t) => { name: 'npm-access-public-pkg', }), }) - const access = requireInject('../../lib/access.js', { - '../../lib/npm.js': { prefix }, - }) - access([ + const access = new Access({ prefix }) + access.exec([ 'public', ], (err) => { t.match( @@ -98,7 +94,7 @@ test('access public on scoped package', (t) => { const prefix = t.testdir({ 'package.json': JSON.stringify({ name }), }) - const access = requireInject('../../lib/access.js', { + const Access = requireInject('../../lib/access.js', { libnpmaccess: { public: (pkg, { registry }) => { t.equal(pkg, name, 'should use pkg name ref') @@ -110,14 +106,12 @@ test('access public on scoped package', (t) => { return true }, }, - '../../lib/npm.js': { - flatOptions: { - registry: 'https://registry.npmjs.org', - }, - prefix, - }, }) - access([ + const access = new Access({ + flatOptions: { registry: 'https://registry.npmjs.org' }, + prefix, + }) + access.exec([ 'public', ], (err) => { t.ifError(err, 'npm access') @@ -129,10 +123,8 @@ test('access public on missing package.json', (t) => { const prefix = t.testdir({ node_modules: {}, }) - const access = requireInject('../../lib/access.js', { - '../../lib/npm.js': { prefix }, - }) - access([ + const access = new Access({ prefix }) + access.exec([ 'public', ], (err) => { t.match( @@ -149,10 +141,8 @@ test('access public on invalid package.json', (t) => { 'package.json': '{\n', node_modules: {}, }) - const access = requireInject('../../lib/access.js', { - '../../lib/npm.js': { prefix }, - }) - access([ + const access = new Access({ prefix }) + access.exec([ 'public', ], (err) => { t.match( @@ -170,10 +160,8 @@ test('access restricted on unscoped package', (t) => { name: 'npm-access-restricted-pkg', }), }) - const access = requireInject('../../lib/access.js', { - '../../lib/npm.js': { prefix }, - }) - access([ + const access = new Access({ prefix }) + access.exec([ 'restricted', ], (err) => { t.match( @@ -191,7 +179,7 @@ test('access restricted on scoped package', (t) => { const prefix = t.testdir({ 'package.json': JSON.stringify({ name }), }) - const access = requireInject('../../lib/access.js', { + const Access = requireInject('../../lib/access.js', { libnpmaccess: { restricted: (pkg, { registry }) => { t.equal(pkg, name, 'should use pkg name ref') @@ -203,14 +191,12 @@ test('access restricted on scoped package', (t) => { return true }, }, - '../../lib/npm.js': { - flatOptions: { - registry: 'https://registry.npmjs.org', - }, - prefix, - }, }) - access([ + const access = new Access({ + flatOptions: { registry: 'https://registry.npmjs.org' }, + prefix, + }) + access.exec([ 'restricted', ], (err) => { t.ifError(err, 'npm access') @@ -222,10 +208,8 @@ test('access restricted on missing package.json', (t) => { const prefix = t.testdir({ node_modules: {}, }) - const access = requireInject('../../lib/access.js', { - '../../lib/npm.js': { prefix }, - }) - access([ + const access = new Access({ prefix }) + access.exec([ 'restricted', ], (err) => { t.match( @@ -242,10 +226,8 @@ test('access restricted on invalid package.json', (t) => { 'package.json': '{\n', node_modules: {}, }) - const access = requireInject('../../lib/access.js', { - '../../lib/npm.js': { prefix }, - }) - access([ + const access = new Access({ prefix }) + access.exec([ 'restricted', ], (err) => { t.match( @@ -259,7 +241,7 @@ test('access restricted on invalid package.json', (t) => { test('access grant read-only', (t) => { t.plan(5) - const access = requireInject('../../lib/access.js', { + const Access = requireInject('../../lib/access.js', { libnpmaccess: { grant: (spec, team, permissions) => { t.equal(spec, '@scoped/another', 'should use expected spec') @@ -268,9 +250,9 @@ test('access grant read-only', (t) => { return true }, }, - '../../lib/npm.js': {}, }) - access([ + const access = new Access({}) + access.exec([ 'grant', 'read-only', 'myorg:myteam', @@ -283,7 +265,7 @@ test('access grant read-only', (t) => { test('access grant read-write', (t) => { t.plan(5) - const access = requireInject('../../lib/access.js', { + const Access = requireInject('../../lib/access.js', { libnpmaccess: { grant: (spec, team, permissions) => { t.equal(spec, '@scoped/another', 'should use expected spec') @@ -292,9 +274,9 @@ test('access grant read-write', (t) => { return true }, }, - '../../lib/npm.js': {}, }) - access([ + const access = new Access({}) + access.exec([ 'grant', 'read-write', 'myorg:myteam', @@ -312,7 +294,7 @@ test('access grant current cwd', (t) => { name: 'yargs', }), }) - const access = requireInject('../../lib/access.js', { + const Access = requireInject('../../lib/access.js', { libnpmaccess: { grant: (spec, team, permissions) => { t.equal(spec, 'yargs', 'should use expected spec') @@ -321,9 +303,9 @@ test('access grant current cwd', (t) => { return true }, }, - '../../lib/npm.js': { prefix }, }) - access([ + const access = new Access({ prefix }) + access.exec([ 'grant', 'read-write', 'myorg:myteam', @@ -334,7 +316,8 @@ test('access grant current cwd', (t) => { }) test('access grant others', (t) => { - access([ + const access = new Access({ flatOptions: {} }) + access.exec([ 'grant', 'rerere', 'myorg:myteam', @@ -350,7 +333,8 @@ test('access grant others', (t) => { }) test('access grant missing team args', (t) => { - access([ + const access = new Access({ flatOptions: {} }) + access.exec([ 'grant', 'read-only', undefined, @@ -366,7 +350,8 @@ test('access grant missing team args', (t) => { }) test('access grant malformed team arg', (t) => { - access([ + const access = new Access({ flatOptions: {} }) + access.exec([ 'grant', 'read-only', 'foo', @@ -383,7 +368,7 @@ test('access grant malformed team arg', (t) => { test('access 2fa-required/2fa-not-required', t => { t.plan(2) - const access = requireInject('../../lib/access.js', { + const Access = requireInject('../../lib/access.js', { libnpmaccess: { tfaRequired: (spec) => { t.equal(spec, '@scope/pkg', 'should use expected spec') @@ -394,15 +379,15 @@ test('access 2fa-required/2fa-not-required', t => { return true }, }, - '../../lib/npm.js': {}, }) + const access = new Access({}) - access(['2fa-required', '@scope/pkg'], er => { + access.exec(['2fa-required', '@scope/pkg'], er => { if (er) throw er }) - access(['2fa-not-required', 'unscoped-pkg'], er => { + access.exec(['2fa-not-required', 'unscoped-pkg'], er => { if (er) throw er }) @@ -410,7 +395,7 @@ test('access 2fa-required/2fa-not-required', t => { test('access revoke', (t) => { t.plan(4) - const access = requireInject('../../lib/access.js', { + const Access = requireInject('../../lib/access.js', { libnpmaccess: { revoke: (spec, team) => { t.equal(spec, '@scoped/another', 'should use expected spec') @@ -418,9 +403,9 @@ test('access revoke', (t) => { return true }, }, - '../../lib/npm.js': {}, }) - access([ + const access = new Access({}) + access.exec([ 'revoke', 'myorg:myteam', '@scoped/another', @@ -431,7 +416,8 @@ test('access revoke', (t) => { }) test('access revoke missing team args', (t) => { - access([ + const access = new Access({ flatOptions: {} }) + access.exec([ 'revoke', undefined, '@scoped/another', @@ -446,7 +432,8 @@ test('access revoke missing team args', (t) => { }) test('access revoke malformed team arg', (t) => { - access([ + const access = new Access({ flatOptions: {} }) + access.exec([ 'revoke', 'foo', '@scoped/another', @@ -462,7 +449,7 @@ test('access revoke malformed team arg', (t) => { test('npm access ls-packages with no team', (t) => { t.plan(3) - const access = requireInject('../../lib/access.js', { + const Access = requireInject('../../lib/access.js', { libnpmaccess: { lsPackages: (entity) => { t.equal(entity, 'foo', 'should use expected entity') @@ -471,9 +458,9 @@ test('npm access ls-packages with no team', (t) => { }, '../../lib/utils/get-identity.js': () => Promise.resolve('foo'), '../../lib/utils/output.js': () => null, - '../../lib/npm.js': {}, }) - access([ + const access = new Access({}) + access.exec([ 'ls-packages', ], (err) => { t.ifError(err, 'npm access') @@ -483,7 +470,7 @@ test('npm access ls-packages with no team', (t) => { test('access ls-packages on team', (t) => { t.plan(3) - const access = requireInject('../../lib/access.js', { + const Access = requireInject('../../lib/access.js', { libnpmaccess: { lsPackages: (entity) => { t.equal(entity, 'myorg:myteam', 'should use expected entity') @@ -491,9 +478,9 @@ test('access ls-packages on team', (t) => { }, }, '../../lib/utils/output.js': () => null, - '../../lib/npm.js': {}, }) - access([ + const access = new Access({}) + access.exec([ 'ls-packages', 'myorg:myteam', ], (err) => { @@ -509,7 +496,7 @@ test('access ls-collaborators on current', (t) => { name: 'yargs', }), }) - const access = requireInject('../../lib/access.js', { + const Access = requireInject('../../lib/access.js', { libnpmaccess: { lsCollaborators: (spec) => { t.equal(spec, 'yargs', 'should use expected spec') @@ -517,9 +504,9 @@ test('access ls-collaborators on current', (t) => { }, }, '../../lib/utils/output.js': () => null, - '../../lib/npm.js': { prefix }, }) - access([ + const access = new Access({ prefix }) + access.exec([ 'ls-collaborators', ], (err) => { t.ifError(err, 'npm access') @@ -529,7 +516,7 @@ test('access ls-collaborators on current', (t) => { test('access ls-collaborators on spec', (t) => { t.plan(3) - const access = requireInject('../../lib/access.js', { + const Access = requireInject('../../lib/access.js', { libnpmaccess: { lsCollaborators: (spec) => { t.equal(spec, 'yargs', 'should use expected spec') @@ -537,9 +524,9 @@ test('access ls-collaborators on spec', (t) => { }, }, '../../lib/utils/output.js': () => null, - '../../lib/npm.js': {}, }) - access([ + const access = new Access({}) + access.exec([ 'ls-collaborators', 'yargs', ], (err) => { diff --git a/deps/npm/test/lib/adduser.js b/deps/npm/test/lib/adduser.js index 36f59e0857..32fd97c1bd 100644 --- a/deps/npm/test/lib/adduser.js +++ b/deps/npm/test/lib/adduser.js @@ -16,7 +16,7 @@ let failSave = false let deletedConfig = {} let registryOutput = '' let setConfig = {} -const authDummy = (options) => { +const authDummy = (npm, options) => { if (!options.fromFlatOptions) throw new Error('did not pass full flatOptions to auth function') @@ -37,46 +37,49 @@ const deleteMock = (key, where) => { [key]: where, } } -const adduser = requireInject('../../lib/adduser.js', { +const npm = { + flatOptions: _flatOptions, + config: { + delete: deleteMock, + get (key, where) { + if (!where || where === 'user') + return _flatOptions[key] + }, + getCredentialsByURI, + async save () { + if (failSave) + throw new Error('error saving user config') + }, + set (key, value, where) { + setConfig = { + ...setConfig, + [key]: { + value, + where, + }, + } + }, + setCredentialsByURI, + }, +} + +const AddUser = requireInject('../../lib/adduser.js', { npmlog: { disableProgress: () => null, notice: (_, msg) => { registryOutput = msg }, }, - '../../lib/npm.js': { - flatOptions: _flatOptions, - config: { - delete: deleteMock, - get (key, where) { - if (!where || where === 'user') - return _flatOptions[key] - }, - getCredentialsByURI, - async save () { - if (failSave) - throw new Error('error saving user config') - }, - set (key, value, where) { - setConfig = { - ...setConfig, - [key]: { - value, - where, - }, - } - }, - setCredentialsByURI, - }, - }, '../../lib/utils/output.js': msg => { result = msg }, '../../lib/auth/legacy.js': authDummy, }) +const adduser = new AddUser(npm) + test('simple login', (t) => { - adduser([], (err) => { + adduser.exec([], (err) => { t.ifError(err, 'npm adduser') t.equal( @@ -129,7 +132,7 @@ test('simple login', (t) => { test('bad auth type', (t) => { _flatOptions.authType = 'foo' - adduser([], (err) => { + adduser.exec([], (err) => { t.match( err, /Error: no such auth module/, @@ -147,7 +150,7 @@ test('bad auth type', (t) => { test('scoped login', (t) => { _flatOptions.scope = '@myscope' - adduser([], (err) => { + adduser.exec([], (err) => { t.ifError(err, 'npm adduser') t.deepEqual( @@ -168,7 +171,7 @@ test('scoped login with valid scoped registry config', (t) => { _flatOptions['@myscope:registry'] = 'https://diff-registry.npmjs.com/' _flatOptions.scope = '@myscope' - adduser([], (err) => { + adduser.exec([], (err) => { t.ifError(err, 'npm adduser') t.deepEqual( @@ -189,7 +192,7 @@ test('scoped login with valid scoped registry config', (t) => { test('save config failure', (t) => { failSave = true - adduser([], (err) => { + adduser.exec([], (err) => { t.match( err, /error saving user config/, diff --git a/deps/npm/test/lib/audit.js b/deps/npm/test/lib/audit.js index 3d6296bac6..6fd9c8a2c9 100644 --- a/deps/npm/test/lib/audit.js +++ b/deps/npm/test/lib/audit.js @@ -1,6 +1,5 @@ const t = require('tap') const requireInject = require('require-inject') -const audit = require('../../lib/audit.js') t.test('should audit using Arborist', t => { let ARB_ARGS = null @@ -10,13 +9,13 @@ t.test('should audit using Arborist', t => { let OUTPUT_CALLED = false let ARB_OBJ = null - const audit = requireInject('../../lib/audit.js', { - '../../lib/npm.js': { - prefix: 'foo', - flatOptions: { - json: false, - }, + const npm = { + prefix: 'foo', + flatOptions: { + json: false, }, + } + const Audit = requireInject('../../lib/audit.js', { 'npm-audit-report': () => { AUDIT_REPORT_CALLED = true return { @@ -32,7 +31,7 @@ t.test('should audit using Arborist', t => { this.auditReport = {} } }, - '../../lib/utils/reify-finish.js': arb => { + '../../lib/utils/reify-finish.js': (npm, arb) => { if (arb !== ARB_OBJ) throw new Error('got wrong object passed to reify-output') @@ -43,8 +42,10 @@ t.test('should audit using Arborist', t => { }, }) + const audit = new Audit(npm) + t.test('audit', t => { - audit([], () => { + audit.exec([], () => { t.match(ARB_ARGS, { audit: true, path: 'foo' }) t.equal(AUDIT_CALLED, true, 'called audit') t.equal(AUDIT_REPORT_CALLED, true, 'called audit report') @@ -54,7 +55,7 @@ t.test('should audit using Arborist', t => { }) t.test('audit fix', t => { - audit(['fix'], () => { + audit.exec(['fix'], () => { t.equal(REIFY_FINISH_CALLED, true, 'called reify output') t.end() }) @@ -64,13 +65,14 @@ t.test('should audit using Arborist', t => { }) t.test('should audit - json', t => { - const audit = requireInject('../../lib/audit.js', { - '../../lib/npm.js': { - prefix: 'foo', - flatOptions: { - json: true, - }, + const npm = { + prefix: 'foo', + flatOptions: { + json: true, }, + } + + const Audit = requireInject('../../lib/audit.js', { 'npm-audit-report': () => ({ report: 'there are vulnerabilities', exitCode: 0, @@ -83,8 +85,9 @@ t.test('should audit - json', t => { '../../lib/utils/reify-output.js': () => {}, '../../lib/utils/output.js': () => {}, }) + const audit = new Audit(npm) - audit([], (err) => { + audit.exec([], (err) => { t.notOk(err, 'no errors') t.end() }) @@ -95,17 +98,17 @@ t.test('report endpoint error', t => { t.test(`json=${json}`, t => { const OUTPUT = [] const LOGS = [] - const mocks = { - '../../lib/npm.js': { - prefix: 'foo', - command: 'audit', - flatOptions: { - json, - }, - log: { - warn: (...warning) => LOGS.push(warning), - }, + const npm = { + prefix: 'foo', + command: 'audit', + flatOptions: { + json, }, + log: { + warn: (...warning) => LOGS.push(warning), + }, + } + const Audit = requireInject('../../lib/audit.js', { 'npm-audit-report': () => { throw new Error('should not call audit report when there are errors') }, @@ -130,15 +133,10 @@ t.test('report endpoint error', t => { '../../lib/utils/output.js': (...msg) => { OUTPUT.push(msg) }, - } - // have to pass mocks to both to get the npm and output set right - const auditError = requireInject('../../lib/utils/audit-error.js', mocks) - const audit = requireInject('../../lib/audit.js', { - ...mocks, - '../../lib/utils/audit-error.js': auditError, }) + const audit = new Audit(npm) - audit([], (err) => { + audit.exec([], (err) => { t.equal(err, 'audit endpoint returned an error') t.strictSame(OUTPUT, [ [ @@ -168,6 +166,8 @@ t.test('report endpoint error', t => { }) t.test('completion', t => { + const Audit = require('../../lib/audit.js') + const audit = new Audit({}) t.test('fix', async t => { t.resolveMatch(audit.completion({ conf: { argv: { remain: ['npm', 'audit'] } } }), ['fix'], 'completes to fix') t.end() diff --git a/deps/npm/test/lib/auth/legacy.js b/deps/npm/test/lib/auth/legacy.js index f926ae1306..f5297c5817 100644 --- a/deps/npm/test/lib/auth/legacy.js +++ b/deps/npm/test/lib/auth/legacy.js @@ -13,19 +13,19 @@ const legacy = requireInject('../../../lib/auth/legacy.js', { }, }, 'npm-profile': profile, - '../../../lib/utils/open-url.js': (url, msg, cb) => { - if (url) - cb() - else { - cb(Object.assign( - new Error('failed open url'), - { code: 'ERROR' } - )) - } + '../../../lib/utils/open-url.js': (npm, url, msg) => { + if (!url) + throw Object.assign(new Error('failed open url'), { code: 'ERROR' }) }, '../../../lib/utils/read-user-info.js': read, }) +const npm = { + config: { + get: () => null, + }, +} + test('login using username/password with token result', async (t) => { profile.login = () => { return { token } @@ -34,7 +34,7 @@ test('login using username/password with token result', async (t) => { const { message, newCreds, - } = await legacy({ + } = await legacy(npm, { creds: { username: 'u', password: 'p', @@ -75,7 +75,7 @@ test('login using username/password with user info result', async (t) => { const { message, newCreds, - } = await legacy({ + } = await legacy(npm, { creds: { username: 'u', password: 'p', @@ -126,7 +126,7 @@ test('login otp requested', async (t) => { const { message, newCreds, - } = await legacy({ + } = await legacy(npm, { creds: { username: 'u', password: 'p', @@ -162,7 +162,7 @@ test('login missing basic credential info', async (t) => { )) await t.rejects( - legacy({ + legacy(npm, { creds: { username: 'u', password: 'p', @@ -196,7 +196,7 @@ test('create new user when user not found', async (t) => { const { message, newCreds, - } = await legacy({ + } = await legacy(npm, { creds: { username: 'u', password: 'p', @@ -246,7 +246,7 @@ test('prompts for user info if required', async (t) => { const { message, newCreds, - } = await legacy({ + } = await legacy(npm, { creds: { alwaysAuth: true, }, @@ -304,7 +304,7 @@ test('request otp when creating new user', async (t) => { } read.otp = () => Promise.resolve('1234') - await legacy({ + await legacy(npm, { creds: { username: 'u', password: 'p', @@ -333,7 +333,7 @@ test('unknown error during user creation', async (t) => { )) await t.rejects( - legacy({ + legacy(npm, { creds: { username: 'u', password: 'p', @@ -358,7 +358,7 @@ test('open url error', async (t) => { } await t.rejects( - legacy({ + legacy(npm, { creds: { username: 'u', password: 'p', @@ -377,7 +377,7 @@ test('open url error', async (t) => { test('login no credentials provided', async (t) => { profile.login = () => ({ token }) - await legacy({ + await legacy(npm, { creds: { username: undefined, password: undefined, @@ -401,7 +401,7 @@ test('login no credentials provided', async (t) => { test('scoped login', async (t) => { profile.login = () => ({ token }) - const { message } = await legacy({ + const { message } = await legacy(npm, { creds: { username: 'u', password: 'p', diff --git a/deps/npm/test/lib/auth/oauth.js b/deps/npm/test/lib/auth/oauth.js index 82d478b52c..c2f4c3443a 100644 --- a/deps/npm/test/lib/auth/oauth.js +++ b/deps/npm/test/lib/auth/oauth.js @@ -9,21 +9,21 @@ test('oauth login', (t) => { scope: 'myscope', } + const npm = { + config: { + set: (key, value) => { + t.equal(key, 'sso-type', 'should define sso-type') + t.equal(value, 'oauth', 'should set sso-type to oauth') + }, + }, + } const oauth = requireInject('../../../lib/auth/oauth.js', { - '../../../lib/auth/sso.js': (opts) => { + '../../../lib/auth/sso.js': (npm, opts) => { t.equal(opts, oauthOpts, 'should forward opts') }, - '../../../lib/npm.js': { - config: { - set: (key, value) => { - t.equal(key, 'sso-type', 'should define sso-type') - t.equal(value, 'oauth', 'should set sso-type to oauth') - }, - }, - }, }) - oauth(oauthOpts) + oauth(npm, oauthOpts) t.end() }) diff --git a/deps/npm/test/lib/auth/saml.js b/deps/npm/test/lib/auth/saml.js index 87fa6688b5..b8c21f649e 100644 --- a/deps/npm/test/lib/auth/saml.js +++ b/deps/npm/test/lib/auth/saml.js @@ -9,21 +9,21 @@ test('saml login', (t) => { scope: 'myscope', } + const npm = { + config: { + set: (key, value) => { + t.equal(key, 'sso-type', 'should define sso-type') + t.equal(value, 'saml', 'should set sso-type to saml') + }, + }, + } const saml = requireInject('../../../lib/auth/saml.js', { - '../../../lib/auth/sso.js': (opts) => { + '../../../lib/auth/sso.js': (npm, opts) => { t.equal(opts, samlOpts, 'should forward opts') }, - '../../../lib/npm.js': { - config: { - set: (key, value) => { - t.equal(key, 'sso-type', 'should define sso-type') - t.equal(value, 'saml', 'should set sso-type to saml') - }, - }, - }, }) - saml(samlOpts) + saml(npm, samlOpts) t.end() }) diff --git a/deps/npm/test/lib/auth/sso.js b/deps/npm/test/lib/auth/sso.js index 1fc04c64cd..6f3d981a6f 100644 --- a/deps/npm/test/lib/auth/sso.js +++ b/deps/npm/test/lib/auth/sso.js @@ -22,17 +22,12 @@ const sso = requireInject('../../../lib/auth/sso.js', { }, 'npm-profile': profile, 'npm-registry-fetch': npmFetch, - '../../../lib/npm.js': { - flatOptions: _flatOptions, - }, - '../../../lib/utils/open-url.js': (url, msg, cb) => { - if (url) - cb() - else { - cb(Object.assign( + '../../../lib/utils/open-url.js': async (npm, url, msg) => { + if (!url) { + throw Object.assign( new Error('failed open url'), { code: 'ERROR' } - )) + ) } }, '../../../lib/utils/otplease.js': (opts, fn) => { @@ -47,11 +42,15 @@ const sso = requireInject('../../../lib/auth/sso.js', { }, }) +const npm = { + flatOptions: _flatOptions, +} + test('empty login', async (t) => { _flatOptions.ssoType = false await t.rejects( - sso({}), + sso(npm, {}), { message: 'Missing option: sso-type' }, 'should throw if no sso-type defined in flatOptions' ) @@ -92,7 +91,7 @@ test('simple login', async (t) => { const { message, newCreds, - } = await sso({ + } = await sso(npm, { creds: {}, registry: 'https://registry.npmjs.org/', scope: '', @@ -157,7 +156,7 @@ test('polling retry', async (t) => { )) } - await sso({ + await sso(npm, { creds: {}, registry: 'https://registry.npmjs.org/', scope: '', @@ -177,7 +176,7 @@ test('polling error', async (t) => { )) await t.rejects( - sso({ + sso(npm, { creds: {}, registry: 'https://registry.npmjs.org/', scope: '', @@ -196,7 +195,7 @@ test('no token retrieved from loginCouch', async (t) => { profile.loginCouch = () => ({}) await t.rejects( - sso({ + sso(npm, { creds: {}, registry: 'https://registry.npmjs.org/', scope: '', @@ -214,7 +213,7 @@ test('no sso url retrieved from loginCouch', async (t) => { profile.loginCouch = () => Promise.resolve({ token }) await t.rejects( - sso({ + sso(npm, { creds: {}, registry: 'https://registry.npmjs.org/', scope: '', @@ -235,7 +234,7 @@ test('scoped login', async (t) => { const { message, newCreds, - } = await sso({ + } = await sso(npm, { creds: {}, registry: 'https://diff-registry.npmjs.org/', scope: 'myscope', diff --git a/deps/npm/test/lib/bin.js b/deps/npm/test/lib/bin.js index c5ed2a91b9..e96eb91af9 100644 --- a/deps/npm/test/lib/bin.js +++ b/deps/npm/test/lib/bin.js @@ -5,14 +5,15 @@ test('bin', (t) => { t.plan(3) const dir = '/bin/dir' - const bin = requireInject('../../lib/bin.js', { - '../../lib/npm.js': { bin: dir, flatOptions: { global: false } }, + const Bin = requireInject('../../lib/bin.js', { '../../lib/utils/output.js': (output) => { t.equal(output, dir, 'prints the correct directory') }, }) - bin([], (err) => { + const bin = new Bin({ bin: dir, flatOptions: { global: false } }) + + bin.exec([], (err) => { t.ifError(err, 'npm bin') t.ok('should have printed directory') }) @@ -30,15 +31,16 @@ test('bin -g', (t) => { } const dir = '/bin/dir' - const bin = requireInject('../../lib/bin.js', { - '../../lib/npm.js': { bin: dir, flatOptions: { global: true } }, + const Bin = requireInject('../../lib/bin.js', { '../../lib/utils/path.js': [dir], '../../lib/utils/output.js': (output) => { t.equal(output, dir, 'prints the correct directory') }, }) - bin([], (err) => { + const bin = new Bin({ bin: dir, flatOptions: { global: true } }) + + bin.exec([], (err) => { t.ifError(err, 'npm bin') t.ok('should have printed directory') }) @@ -56,15 +58,15 @@ test('bin -g (not in path)', (t) => { } const dir = '/bin/dir' - const bin = requireInject('../../lib/bin.js', { - '../../lib/npm.js': { bin: dir, flatOptions: { global: true } }, + const Bin = requireInject('../../lib/bin.js', { '../../lib/utils/path.js': ['/not/my/dir'], '../../lib/utils/output.js': (output) => { t.equal(output, dir, 'prints the correct directory') }, }) + const bin = new Bin({ bin: dir, flatOptions: { global: true } }) - bin([], (err) => { + bin.exec([], (err) => { t.ifError(err, 'npm bin') t.ok('should have printed directory') }) diff --git a/deps/npm/test/lib/birthday.js b/deps/npm/test/lib/birthday.js index 3b8110fc8f..c818223fb5 100644 --- a/deps/npm/test/lib/birthday.js +++ b/deps/npm/test/lib/birthday.js @@ -1,5 +1,4 @@ const t = require('tap') -const requireInject = require('require-inject') const npm = { flatOptions: { yes: false, @@ -17,10 +16,9 @@ const npm = { }, } -const birthday = requireInject('../../lib/birthday.js', { - '../../lib/npm.js': npm, -}) +const Birthday = require('../../lib/birthday.js') +const birthday = new Birthday(npm) let calledCb = false -birthday([], () => calledCb = true) +birthday.exec([], () => calledCb = true) t.equal(calledCb, true, 'called the callback') diff --git a/deps/npm/test/lib/bugs.js b/deps/npm/test/lib/bugs.js index 992bd9f614..e98131f113 100644 --- a/deps/npm/test/lib/bugs.js +++ b/deps/npm/test/lib/bugs.js @@ -43,17 +43,18 @@ const pacote = { // keep a tally of which urls got opened const opened = {} -const openUrl = (url, errMsg, cb) => { +const openUrl = async (npm, url, errMsg) => { opened[url] = opened[url] || 0 opened[url]++ - process.nextTick(cb) } -const bugs = requireInject('../../lib/bugs.js', { +const Bugs = requireInject('../../lib/bugs.js', { pacote, '../../lib/utils/open-url.js': openUrl, }) +const bugs = new Bugs({ flatOptions: {} }) + t.test('open bugs urls', t => { const expect = { nobugs: 'https://www.npmjs.com/package/nobugs', @@ -68,7 +69,7 @@ t.test('open bugs urls', t => { t.plan(keys.length) keys.forEach(pkg => { t.test(pkg, t => { - bugs([pkg], (er) => { + bugs.exec([pkg], (er) => { if (er) throw er t.equal(opened[expect[pkg]], 1, 'opened expected url', {opened}) @@ -79,7 +80,7 @@ t.test('open bugs urls', t => { }) t.test('open default package if none specified', t => { - bugs([], (er) => { + bugs.exec([], (er) => { if (er) throw er t.equal(opened['https://example.com'], 2, 'opened expected url', {opened}) diff --git a/deps/npm/test/lib/cache.js b/deps/npm/test/lib/cache.js index 05d269dd4d..67499f37e9 100644 --- a/deps/npm/test/lib/cache.js +++ b/deps/npm/test/lib/cache.js @@ -58,27 +58,26 @@ const cacache = { }, } -const mocks = { +const Cache = requireInject('../../lib/cache.js', { cacache, npmlog, pacote, rimraf, - '../../lib/npm.js': npm, '../../lib/utils/output.js': output, '../../lib/utils/usage.js': usageUtil, -} +}) -const cache = requireInject('../../lib/cache.js', mocks) +const cache = new Cache(npm) t.test('cache no args', t => { - cache([], err => { + cache.exec([], err => { t.equal(err.message, 'usage instructions', 'should throw usage instructions') t.end() }) }) t.test('cache clean', t => { - cache(['clean'], err => { + cache.exec(['clean'], err => { t.match(err.message, 'the npm cache self-heals', 'should throw warning') t.end() }) @@ -91,7 +90,7 @@ t.test('cache clean (force)', t => { flatOptions.force = false }) - cache(['clear'], err => { + cache.exec(['clear'], err => { t.ifError(err) t.equal(rimrafPath, path.join(npm.cache, '_cacache')) t.end() @@ -99,7 +98,7 @@ t.test('cache clean (force)', t => { }) t.test('cache clean with arg', t => { - cache(['rm', 'pkg'], err => { + cache.exec(['rm', 'pkg'], err => { t.match(err.message, 'does not accept arguments', 'should throw error') t.end() }) @@ -110,7 +109,7 @@ t.test('cache add no arg', t => { logOutput = [] }) - cache(['add'], err => { + cache.exec(['add'], err => { t.strictSame(logOutput, [ ['silly', 'cache add', 'args', []], ], 'logs correctly') @@ -126,7 +125,7 @@ t.test('cache add pkg only', t => { tarballStreamOpts = {} }) - cache(['add', 'mypkg'], err => { + cache.exec(['add', 'mypkg'], err => { t.ifError(err) t.strictSame(logOutput, [ ['silly', 'cache add', 'args', ['mypkg']], @@ -145,7 +144,7 @@ t.test('cache add pkg w/ spec modifier', t => { tarballStreamOpts = {} }) - cache(['add', 'mypkg', 'latest'], err => { + cache.exec(['add', 'mypkg', 'latest'], err => { t.ifError(err) t.strictSame(logOutput, [ ['silly', 'cache add', 'args', ['mypkg', 'latest']], @@ -162,7 +161,7 @@ t.test('cache verify', t => { outputOutput = [] }) - cache(['verify'], err => { + cache.exec(['verify'], err => { t.ifError(err) t.match(outputOutput, [ `Cache verified and compressed (${path.join(npm.cache, '_cacache')})`, @@ -189,7 +188,7 @@ t.test('cache verify w/ extra output', t => { delete cacacheVerifyStats.missingContent }) - cache(['check'], err => { + cache.exec(['check'], err => { t.ifError(err) t.match(outputOutput, [ `Cache verified and compressed (~${path.join('/fake/path', '_cacache')})`, diff --git a/deps/npm/test/lib/ci.js b/deps/npm/test/lib/ci.js index 28c66b056c..3419218ef9 100644 --- a/deps/npm/test/lib/ci.js +++ b/deps/npm/test/lib/ci.js @@ -9,19 +9,8 @@ const requireInject = require('require-inject') test('should ignore scripts with --ignore-scripts', (t) => { const SCRIPTS = [] let REIFY_CALLED = false - const ci = requireInject('../../lib/ci.js', { + const CI = requireInject('../../lib/ci.js', { '../../lib/utils/reify-finish.js': async () => {}, - '../../lib/npm.js': { - globalDir: 'path/to/node_modules/', - prefix: 'foo', - flatOptions: { - global: false, - ignoreScripts: true, - }, - config: { - get: () => false, - }, - }, '@npmcli/run-script': ({ event }) => { SCRIPTS.push(event) }, @@ -32,7 +21,20 @@ test('should ignore scripts with --ignore-scripts', (t) => { } }, }) - ci([], er => { + + const ci = new CI({ + globalDir: 'path/to/node_modules/', + prefix: 'foo', + flatOptions: { + global: false, + ignoreScripts: true, + }, + config: { + get: () => false, + }, + }) + + ci.exec([], er => { if (er) throw er t.equal(REIFY_CALLED, true, 'called reify') @@ -87,13 +89,7 @@ test('should use Arborist and run-script', (t) => { const expectRimrafs = 3 let actualRimrafs = 0 - const ci = requireInject('../../lib/ci.js', { - '../../lib/npm.js': { - prefix: path, - flatOptions: { - global: false, - }, - }, + const CI = requireInject('../../lib/ci.js', { '../../lib/utils/reify-finish.js': async () => {}, '@npmcli/run-script': opts => { t.match(opts, { event: scripts.shift() }) @@ -118,7 +114,15 @@ test('should use Arborist and run-script', (t) => { t.ok(arb, 'gets arborist tree') }, }) - ci(null, er => { + + const ci = new CI({ + prefix: path, + flatOptions: { + global: false, + }, + }) + + ci.exec(null, er => { if (er) throw er for (const [msg, result] of Object.entries(timers)) @@ -131,13 +135,7 @@ test('should use Arborist and run-script', (t) => { }) test('should pass flatOptions to Arborist.reify', (t) => { - const ci = requireInject('../../lib/ci.js', { - '../../lib/npm.js': { - prefix: 'foo', - flatOptions: { - production: true, - }, - }, + const CI = requireInject('../../lib/ci.js', { '../../lib/utils/reify-finish.js': async () => {}, '@npmcli/run-script': opts => {}, '@npmcli/arborist': function () { @@ -148,7 +146,13 @@ test('should pass flatOptions to Arborist.reify', (t) => { } }, }) - ci(null, er => { + const ci = new CI({ + prefix: 'foo', + flatOptions: { + production: true, + }, + }) + ci.exec(null, er => { if (er) throw er }) @@ -160,13 +164,7 @@ test('should throw if package-lock.json or npm-shrinkwrap missing', (t) => { 'package.json': 'some info', }) - const ci = requireInject('../../lib/ci.js', { - '../../lib/npm.js': { - prefix: testDir, - flatOptions: { - global: false, - }, - }, + const CI = requireInject('../../lib/ci.js', { '@npmcli/run-script': opts => {}, '../../lib/utils/reify-finish.js': async () => {}, npmlog: { @@ -175,7 +173,13 @@ test('should throw if package-lock.json or npm-shrinkwrap missing', (t) => { }, }, }) - ci(null, (err, res) => { + const ci = new CI({ + prefix: testDir, + flatOptions: { + global: false, + }, + }) + ci.exec(null, (err, res) => { t.ok(err, 'throws error when there is no package-lock') t.notOk(res) t.end() @@ -183,17 +187,17 @@ test('should throw if package-lock.json or npm-shrinkwrap missing', (t) => { }) test('should throw ECIGLOBAL', (t) => { - const ci = requireInject('../../lib/ci.js', { - '../../lib/npm.js': { - prefix: 'foo', - flatOptions: { - global: true, - }, - }, + const CI = requireInject('../../lib/ci.js', { '@npmcli/run-script': opts => {}, '../../lib/utils/reify-finish.js': async () => {}, }) - ci(null, (err, res) => { + const ci = new CI({ + prefix: 'foo', + flatOptions: { + global: true, + }, + }) + ci.exec(null, (err, res) => { t.equals(err.code, 'ECIGLOBAL', 'throws error with global packages') t.notOk(res) t.end() @@ -207,13 +211,7 @@ test('should remove existing node_modules before installing', (t) => { }, }) - const ci = requireInject('../../lib/ci.js', { - '../../lib/npm.js': { - prefix: testDir, - flatOptions: { - global: false, - }, - }, + const CI = requireInject('../../lib/ci.js', { '@npmcli/run-script': opts => {}, '../../lib/utils/reify-finish.js': async () => {}, '@npmcli/arborist': function () { @@ -229,7 +227,14 @@ test('should remove existing node_modules before installing', (t) => { }, }) - ci(null, er => { + const ci = new CI({ + prefix: testDir, + flatOptions: { + global: false, + }, + }) + + ci.exec(null, er => { if (er) throw er }) diff --git a/deps/npm/test/lib/completion.js b/deps/npm/test/lib/completion.js index 19f70df20e..89e8134ebb 100644 --- a/deps/npm/test/lib/completion.js +++ b/deps/npm/test/lib/completion.js @@ -75,8 +75,7 @@ const deref = (cmd) => { return cmd } -const completion = requireInject('../../lib/completion.js', { - '../../lib/npm.js': npm, +const Completion = requireInject('../../lib/completion.js', { '../../lib/utils/cmd-list.js': cmdList, '../../lib/utils/config.js': config, '../../lib/utils/deref-command.js': deref, @@ -85,6 +84,7 @@ const completion = requireInject('../../lib/completion.js', { output.push(line) }, }) +const completion = new Completion(npm) test('completion completion', async t => { const home = process.env.HOME @@ -125,11 +125,13 @@ test('completion completion wrong word count', async t => { }) test('completion errors in windows without bash', t => { - const compl = requireInject('../../lib/completion.js', { + const Compl = requireInject('../../lib/completion.js', { '../../lib/utils/is-windows-shell.js': true, }) - compl({}, (err) => { + const compl = new Compl() + + compl.exec({}, (err) => { t.match(err, { code: 'ENOTSUP', message: /completion supported only in MINGW/, @@ -162,7 +164,7 @@ test('dump script when completion is not being attempted', t => { }) } - completion({}, (err) => { + completion.exec({}, (err) => { if (err) throw err @@ -195,7 +197,7 @@ test('dump script exits correctly when EPIPE is emitted on stdout', t => { }) } - completion({}, (err) => { + completion.exec({}, (err) => { if (err) throw err @@ -228,7 +230,7 @@ test('non EPIPE errors cause failures', t => { }) } - completion({}, (err) => { + completion.exec({}, (err) => { t.equal(err.errno, 'ESOMETHINGELSE', 'propagated error') t.equal(data, completionScript, 'wrote the completion script') t.end() @@ -248,7 +250,7 @@ test('completion completes single command name', t => { output.length = 0 }) - completion(['npm', 'c'], (err, res) => { + completion.exec(['npm', 'c'], (err, res) => { if (err) throw err @@ -270,7 +272,7 @@ test('completion completes command names', t => { output.length = 0 }) - completion(['npm', 'a'], (err, res) => { + completion.exec(['npm', 'a'], (err, res) => { if (err) throw err @@ -292,7 +294,7 @@ test('completion of invalid command name does nothing', t => { output.length = 0 }) - completion(['npm', 'compute'], (err, res) => { + completion.exec(['npm', 'compute'], (err, res) => { if (err) throw err @@ -314,7 +316,7 @@ test('handles async completion function', t => { output.length = 0 }) - completion(['npm', 'promise', ''], (err, res) => { + completion.exec(['npm', 'promise', ''], (err, res) => { if (err) throw err @@ -343,7 +345,7 @@ test('completion triggers command completions', t => { output.length = 0 }) - completion(['npm', 'access', ''], (err, res) => { + completion.exec(['npm', 'access', ''], (err, res) => { if (err) throw err @@ -372,7 +374,7 @@ test('completion triggers filtered command completions', t => { output.length = 0 }) - completion(['npm', 'access', 'p'], (err, res) => { + completion.exec(['npm', 'access', 'p'], (err, res) => { if (err) throw err @@ -401,7 +403,7 @@ test('completions for commands that return nested arrays are joined', t => { output.length = 0 }) - completion(['npm', 'completion', ''], (err, res) => { + completion.exec(['npm', 'completion', ''], (err, res) => { if (err) throw err @@ -430,7 +432,7 @@ test('completions for commands that return nothing work correctly', t => { output.length = 0 }) - completion(['npm', 'donothing', ''], (err, res) => { + completion.exec(['npm', 'donothing', ''], (err, res) => { if (err) throw err @@ -459,7 +461,7 @@ test('completions for commands that return a single item work correctly', t => { output.length = 0 }) - completion(['npm', 'driveaboat', ''], (err, res) => { + completion.exec(['npm', 'driveaboat', ''], (err, res) => { if (err) throw err @@ -489,7 +491,7 @@ test('command completion for commands with no completion return no results', t = }) // quotes around adduser are to ensure coverage when unescaping commands - completion(['npm', '\'adduser\'', ''], (err, res) => { + completion.exec(['npm', '\'adduser\'', ''], (err, res) => { if (err) throw err @@ -520,7 +522,7 @@ test('command completion errors propagate', t => { accessCompletionError = false }) - completion(['npm', 'access', ''], (err, res) => { + completion.exec(['npm', 'access', ''], (err, res) => { t.match(err, /access completion failed/, 'catches the appropriate error') t.strictSame(npmConfig, { argv: { @@ -547,7 +549,7 @@ test('completion can complete flags', t => { output.length = 0 }) - completion(['npm', 'install', '--'], (err, res) => { + completion.exec(['npm', 'install', '--'], (err, res) => { if (err) throw err @@ -570,7 +572,7 @@ test('double dashes escape from flag completion', t => { output.length = 0 }) - completion(['npm', '--', 'install', '--'], (err, res) => { + completion.exec(['npm', '--', 'install', '--'], (err, res) => { if (err) throw err @@ -593,7 +595,7 @@ test('completion cannot complete options that take a value in mid-command', t => output.length = 0 }) - completion(['npm', '--registry', 'install'], (err, res) => { + completion.exec(['npm', '--registry', 'install'], (err, res) => { if (err) throw err diff --git a/deps/npm/test/lib/config.js b/deps/npm/test/lib/config.js index edaa6486cd..c2420aefb4 100644 --- a/deps/npm/test/lib/config.js +++ b/deps/npm/test/lib/config.js @@ -68,17 +68,17 @@ const usageUtil = () => 'usage instructions' const mocks = { '../../lib/utils/config.js': { defaults, types }, - '../../lib/npm.js': npm, '../../lib/utils/output.js': msg => { result = msg }, '../../lib/utils/usage.js': usageUtil, } -const config = requireInject('../../lib/config.js', mocks) +const Config = requireInject('../../lib/config.js', mocks) +const config = new Config(npm) t.test('config no args', t => { - config([], (err) => { + config.exec([], (err) => { t.match(err, /usage instructions/, 'should not error out on empty locations') t.end() }) @@ -94,7 +94,7 @@ t.test('config list', t => { delete npm.config.find }) - config(['list'], (err) => { + config.exec(['list'], (err) => { t.ifError(err, 'npm config list') t.matchSnapshot(result, 'should list configs') }) @@ -120,7 +120,7 @@ t.test('config list overrides', t => { delete npm.config.find }) - config(['list'], (err) => { + config.exec(['list'], (err) => { t.ifError(err, 'npm config list') t.matchSnapshot(result, 'should list overridden configs') }) @@ -138,7 +138,7 @@ t.test('config list --long', t => { result = '' }) - config(['list'], (err) => { + config.exec(['list'], (err) => { t.ifError(err, 'npm config list --long') t.matchSnapshot(result, 'should list all configs') }) @@ -163,7 +163,7 @@ t.test('config list --json', t => { result = '' }) - config(['list'], (err) => { + config.exec(['list'], (err) => { t.ifError(err, 'npm config list --json') t.deepEqual( JSON.parse(result), @@ -179,7 +179,7 @@ t.test('config list --json', t => { }) t.test('config delete no args', t => { - config(['delete'], (err) => { + config.exec(['delete'], (err) => { t.equal( err.message, 'usage instructions', @@ -202,7 +202,7 @@ t.test('config delete key', t => { t.equal(where, 'user', 'should save user config post-delete') } - config(['delete', 'foo'], (err) => { + config.exec(['delete', 'foo'], (err) => { t.ifError(err, 'npm config delete key') }) @@ -229,7 +229,7 @@ t.test('config delete multiple key', t => { t.equal(where, 'user', 'should save user config post-delete') } - config(['delete', 'foo', 'bar'], (err) => { + config.exec(['delete', 'foo', 'bar'], (err) => { t.ifError(err, 'npm config delete keys') }) @@ -252,7 +252,7 @@ t.test('config delete key --global', t => { } flatOptions.global = true - config(['delete', 'foo'], (err) => { + config.exec(['delete', 'foo'], (err) => { t.ifError(err, 'npm config delete key --global') }) @@ -264,7 +264,7 @@ t.test('config delete key --global', t => { }) t.test('config set no args', t => { - config(['set'], (err) => { + config.exec(['set'], (err) => { t.equal( err.message, 'usage instructions', @@ -287,7 +287,7 @@ t.test('config set key', t => { t.equal(where, 'user', 'should save user config') } - config(['set', 'foo', 'bar'], (err) => { + config.exec(['set', 'foo', 'bar'], (err) => { t.ifError(err, 'npm config set key') }) @@ -310,7 +310,7 @@ t.test('config set key=val', t => { t.equal(where, 'user', 'should save user config') } - config(['set', 'foo=bar'], (err) => { + config.exec(['set', 'foo=bar'], (err) => { t.ifError(err, 'npm config set key') }) @@ -341,7 +341,7 @@ t.test('config set multiple keys', t => { t.equal(where, 'user', 'should save user config') } - config(['set', ...args], (err) => { + config.exec(['set', ...args], (err) => { t.ifError(err, 'npm config set key') }) @@ -364,7 +364,7 @@ t.test('config set key to empty value', t => { t.equal(where, 'user', 'should save user config') } - config(['set', 'foo'], (err) => { + config.exec(['set', 'foo'], (err) => { t.ifError(err, 'npm config set key to empty value') }) @@ -392,7 +392,7 @@ t.test('config set invalid key', t => { delete npm.log.warn }) - config(['set', 'foo', 'bar'], (err) => { + config.exec(['set', 'foo', 'bar'], (err) => { t.ifError(err, 'npm config set invalid key') }) }) @@ -411,7 +411,7 @@ t.test('config set key --global', t => { } flatOptions.global = true - config(['set', 'foo', 'bar'], (err) => { + config.exec(['set', 'foo', 'bar'], (err) => { t.ifError(err, 'npm config set key --global') }) @@ -432,7 +432,7 @@ t.test('config get no args', t => { delete npm.config.find }) - config(['get'], (err) => { + config.exec(['get'], (err) => { t.ifError(err, 'npm config get no args') t.matchSnapshot(result, 'should list configs on config get no args') }) @@ -451,7 +451,7 @@ t.test('config get key', t => { throw new Error('should not save') } - config(['get', 'foo'], (err) => { + config.exec(['get', 'foo'], (err) => { t.ifError(err, 'npm config get key') }) @@ -479,7 +479,7 @@ t.test('config get multiple keys', t => { throw new Error('should not save') } - config(['get', 'foo', 'bar'], (err) => { + config.exec(['get', 'foo', 'bar'], (err) => { t.ifError(err, 'npm config get multiple keys') t.equal(result, 'foo=asdf\nbar=asdf') }) @@ -492,7 +492,7 @@ t.test('config get multiple keys', t => { }) t.test('config get private key', t => { - config(['get', '//private-reg.npmjs.org/:_authThoken'], (err) => { + config.exec(['get', '//private-reg.npmjs.org/:_authThoken'], (err) => { t.match( err, /The \/\/private-reg.npmjs.org\/:_authThoken option is protected, and cannot be retrieved in this way/, @@ -538,16 +538,19 @@ sign-git-commit=true` }, }, } - const config = requireInject('../../lib/config.js', editMocks) - config(['edit'], (err) => { + const Config = requireInject('../../lib/config.js', editMocks) + const config = new Config(npm) + + config.exec(['edit'], (err) => { t.ifError(err, 'npm config edit') // test no config file result editMocks.fs.readFile = (p, e, cb) => { cb(new Error('ERR')) } - const config = requireInject('../../lib/config.js', editMocks) - config(['edit'], (err) => { + const Config = requireInject('../../lib/config.js', editMocks) + const config = new Config(npm) + config.exec(['edit'], (err) => { t.ifError(err, 'npm config edit') }) }) @@ -594,8 +597,9 @@ t.test('config edit --global', t => { }, }, } - const config = requireInject('../../lib/config.js', editMocks) - config(['edit'], (err) => { + const Config = requireInject('../../lib/config.js', editMocks) + const config = new Config(npm) + config.exec(['edit'], (err) => { t.match(err, /exited with code: 137/, 'propagated exit code from editor') }) diff --git a/deps/npm/test/lib/dedupe.js b/deps/npm/test/lib/dedupe.js index b14185525b..3e8b2f4c01 100644 --- a/deps/npm/test/lib/dedupe.js +++ b/deps/npm/test/lib/dedupe.js @@ -1,29 +1,29 @@ const { test } = require('tap') const requireInject = require('require-inject') -test('should throw in global mode', (t) => { - const dedupe = requireInject('../../lib/dedupe.js', { - '../../lib/npm.js': { - flatOptions: { - global: true, - }, +const npm = (base) => { + const config = base.config + return { + ...base, + flatOptions: { dryRun: false }, + config: { + get: (k) => config[k], }, - }) + } +} + +test('should throw in global mode', (t) => { + const Dedupe = requireInject('../../lib/dedupe.js') + const dedupe = new Dedupe(npm({ config: { global: true }})) - dedupe([], er => { + dedupe.exec([], er => { t.match(er, { code: 'EDEDUPEGLOBAL' }, 'throws EDEDUPEGLOBAL') t.end() }) }) test('should remove dupes using Arborist', (t) => { - const dedupe = requireInject('../../lib/dedupe.js', { - '../../lib/npm.js': { - prefix: 'foo', - flatOptions: { - dryRun: 'false', - }, - }, + const Dedupe = requireInject('../../lib/dedupe.js', { '@npmcli/arborist': function (args) { t.ok(args, 'gets options object') t.ok(args.path, 'gets path option') @@ -32,11 +32,17 @@ test('should remove dupes using Arborist', (t) => { t.ok(true, 'dedupe is called') } }, - '../../lib/utils/reify-finish.js': (arb) => { + '../../lib/utils/reify-finish.js': (npm, arb) => { t.ok(arb, 'gets arborist tree') }, }) - dedupe({ dryRun: true }, er => { + const dedupe = new Dedupe(npm({ + prefix: 'foo', + config: { + 'dry-run': 'true', + }, + })) + dedupe.exec([], er => { if (er) throw er t.ok(true, 'callback is called') @@ -45,20 +51,20 @@ test('should remove dupes using Arborist', (t) => { }) test('should remove dupes using Arborist - no arguments', (t) => { - const dedupe = requireInject('../../lib/dedupe.js', { - '../../lib/npm.js': { - prefix: 'foo', - flatOptions: { - dryRun: 'true', - }, - }, + const Dedupe = requireInject('../../lib/dedupe.js', { '@npmcli/arborist': function (args) { t.ok(args.dryRun, 'gets dryRun from flatOptions') this.dedupe = () => {} }, '../../lib/utils/reify-output.js': () => {}, }) - dedupe(null, () => { + const dedupe = new Dedupe(npm({ + prefix: 'foo', + config: { + 'dry-run': true, + }, + })) + dedupe.exec(null, () => { t.end() }) }) diff --git a/deps/npm/test/lib/deprecate.js b/deps/npm/test/lib/deprecate.js index fd563de120..03100166a0 100644 --- a/deps/npm/test/lib/deprecate.js +++ b/deps/npm/test/lib/deprecate.js @@ -18,10 +18,7 @@ npmFetch.json = async (uri, opts) => { } } -const deprecate = requireInject('../../lib/deprecate.js', { - '../../lib/npm.js': { - flatOptions: { registry: 'https://registry.npmjs.org' }, - }, +const Deprecate = requireInject('../../lib/deprecate.js', { '../../lib/utils/get-identity.js': async () => getIdentityImpl(), '../../lib/utils/otplease.js': async (opts, fn) => fn(opts), libnpmaccess: { @@ -30,16 +27,19 @@ const deprecate = requireInject('../../lib/deprecate.js', { 'npm-registry-fetch': npmFetch, }) +const deprecate = new Deprecate({ + flatOptions: { registry: 'https://registry.npmjs.org' }, +}) + test('completion', async t => { const defaultIdentityImpl = getIdentityImpl t.teardown(() => { getIdentityImpl = defaultIdentityImpl }) - const { completion } = deprecate - const testComp = async (argv, expect) => { - const res = await completion({ conf: { argv: { remain: argv } } }) + const res = + await deprecate.completion({ conf: { argv: { remain: argv } } }) t.strictSame(res, expect, `completion: ${argv}`) } @@ -59,21 +59,21 @@ test('completion', async t => { }) test('no args', t => { - deprecate([], (err) => { + deprecate.exec([], (err) => { t.match(err, /Usage: npm deprecate/, 'logs usage') t.end() }) }) test('only one arg', t => { - deprecate(['foo'], (err) => { + deprecate.exec(['foo'], (err) => { t.match(err, /Usage: npm deprecate/, 'logs usage') t.end() }) }) test('invalid semver range', t => { - deprecate(['foo@notaversion', 'this will fail'], (err) => { + deprecate.exec(['foo@notaversion', 'this will fail'], (err) => { t.match(err, /invalid version range/, 'logs semver error') t.end() }) @@ -84,7 +84,7 @@ test('deprecates given range', t => { npmFetchBody = null }) - deprecate(['foo@1.0.0', 'this version is deprecated'], (err) => { + deprecate.exec(['foo@1.0.0', 'this version is deprecated'], (err) => { if (err) throw err @@ -110,7 +110,7 @@ test('deprecates all versions when no range is specified', t => { npmFetchBody = null }) - deprecate(['foo', 'this version is deprecated'], (err) => { + deprecate.exec(['foo', 'this version is deprecated'], (err) => { if (err) throw err diff --git a/deps/npm/test/lib/diff.js b/deps/npm/test/lib/diff.js index 926c54fdf1..2af3bd69bc 100644 --- a/deps/npm/test/lib/diff.js +++ b/deps/npm/test/lib/diff.js @@ -28,7 +28,6 @@ const mocks = { npmlog: { info: noop, verbose: noop }, libnpmdiff: (...args) => libnpmdiff(...args), 'npm-registry-fetch': async () => ({}), - '../../lib/npm.js': npm, '../../lib/utils/output.js': noop, '../../lib/utils/read-local-package.js': async () => rlp(), '../../lib/utils/usage.js': () => 'usage instructions', @@ -42,7 +41,8 @@ t.afterEach(cb => { cb() }) -const diff = requireInject('../../lib/diff.js', mocks) +const Diff = requireInject('../../lib/diff.js', mocks) +const diff = new Diff(npm) t.test('no args', t => { t.test('in a project dir', t => { @@ -56,7 +56,7 @@ t.test('no args', t => { } npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -65,7 +65,7 @@ t.test('no args', t => { t.test('no args, missing package.json name in cwd', t => { rlp = () => undefined - diff([], err => { + diff.exec([], err => { t.match( err, /Needs multiple arguments to compare or run from a project dir./, @@ -80,7 +80,7 @@ t.test('no args', t => { throw new Error('ERR') } - diff([], err => { + diff.exec([], err => { t.match( err, /Needs multiple arguments to compare or run from a project dir./, @@ -106,7 +106,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['foo@1.0.0'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -120,7 +120,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['foo@1.0.0'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { t.match( err, /Needs multiple arguments to compare or run from a project dir./, @@ -142,7 +142,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['foo@~1.0.0'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -160,7 +160,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['2.1.4'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -172,7 +172,7 @@ t.test('single arg', t => { } npm.flatOptions.diff = ['2.1.4'] - diff([], err => { + diff.exec([], err => { t.match( err, /Needs multiple arguments to compare or run from a project dir./, @@ -200,7 +200,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['2.1.4'] npm.flatOptions.prefix = path - diff(['./foo.js', './bar.js'], err => { + diff.exec(['./foo.js', './bar.js'], err => { if (err) throw err }) @@ -224,7 +224,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['bar@1.0.0'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -250,7 +250,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['simple-output'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -264,7 +264,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['bar'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { t.match( err, /Needs multiple arguments to compare or run from a project dir./, @@ -297,7 +297,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['bar'] npm.flatOptions.prefix = path - const diff = requireInject('../../lib/diff.js', { + const Diff = requireInject('../../lib/diff.js', { ...mocks, pacote: { packument: (spec) => { @@ -313,8 +313,9 @@ t.test('single arg', t => { t.equal(b, 'bar@1.8.10', 'should have possible semver range spec') }, }) + const diff = new Diff(npm) - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -359,7 +360,7 @@ t.test('single arg', t => { npm.flatOptions.prefix = resolve(path, 'project') npm.globalDir = resolve(path, 'globalDir/lib/node_modules') - const diff = requireInject('../../lib/diff.js', { + const Diff = requireInject('../../lib/diff.js', { ...mocks, pacote: { packument: (spec) => { @@ -375,8 +376,9 @@ t.test('single arg', t => { t.equal(b, 'lorem@2.1.0', 'should have possible semver range spec') }, }) + const diff = new Diff(npm) - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -410,7 +412,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['bar@2.0.0'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -445,7 +447,7 @@ t.test('single arg', t => { }), }) - const diff = requireInject('../../lib/diff.js', { + const Diff = requireInject('../../lib/diff.js', { ...mocks, '../../lib/utils/read-local-package.js': async () => 'my-project', pacote: { @@ -462,11 +464,12 @@ t.test('single arg', t => { t.equal(b, 'lorem@2.2.2', 'should have expected target spec') }, }) + const diff = new Diff(npm) npm.flatOptions.diff = ['lorem'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -481,7 +484,7 @@ t.test('single arg', t => { }), }) - const diff = requireInject('../../lib/diff.js', { + const Diff = requireInject('../../lib/diff.js', { ...mocks, '../../lib/utils/read-local-package.js': async () => 'my-project', '@npmcli/arborist': class { @@ -494,11 +497,12 @@ t.test('single arg', t => { t.equal(b, `file:${path}`, 'should target current cwd') }, }) + const diff = new Diff(npm) npm.flatOptions.diff = ['lorem'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -517,7 +521,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['bar'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -535,7 +539,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['my-project'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -553,7 +557,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['/path/to/other-dir'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -564,7 +568,7 @@ t.test('single arg', t => { npm.flatOptions.diff = ['git+https://github.com/user/foo'] - diff([], err => { + diff.exec([], err => { t.match( err, /Spec type not supported./, @@ -588,7 +592,7 @@ t.test('first arg is a qualified spec', t => { } npm.flatOptions.diff = ['bar@1.0.0', 'bar@^2.0.0'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -622,7 +626,7 @@ t.test('first arg is a qualified spec', t => { npm.flatOptions.prefix = path npm.flatOptions.diff = ['bar@2.0.0', 'bar'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -638,7 +642,7 @@ t.test('first arg is a qualified spec', t => { t.equal(b, 'bar@2.0.0', 'should use name from first arg') } - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -653,7 +657,7 @@ t.test('first arg is a qualified spec', t => { } npm.flatOptions.diff = ['bar@1.0.0', 'bar-fork'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -691,7 +695,7 @@ t.test('first arg is a known dependency name', t => { npm.flatOptions.prefix = path npm.flatOptions.diff = ['bar', 'bar@2.0.0'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -731,7 +735,7 @@ t.test('first arg is a known dependency name', t => { npm.flatOptions.prefix = path npm.flatOptions.diff = ['bar', 'bar-fork'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -765,7 +769,7 @@ t.test('first arg is a known dependency name', t => { npm.flatOptions.prefix = path npm.flatOptions.diff = ['bar', '2.0.0'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -799,7 +803,7 @@ t.test('first arg is a known dependency name', t => { npm.flatOptions.prefix = path npm.flatOptions.diff = ['bar', 'bar-fork'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -819,7 +823,7 @@ t.test('first arg is a valid semver range', t => { t.equal(b, 'bar@2.0.0', 'should use expected spec') } - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -853,7 +857,7 @@ t.test('first arg is a valid semver range', t => { npm.flatOptions.prefix = path npm.flatOptions.diff = ['1.0.0', 'bar'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -869,7 +873,7 @@ t.test('first arg is a valid semver range', t => { } npm.flatOptions.diff = ['1.0.0', '2.0.0'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -883,7 +887,7 @@ t.test('first arg is a valid semver range', t => { npm.flatOptions.diff = ['1.0.0', '2.0.0'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { t.match( err, /Needs to be run from a project dir in order to diff two versions./, @@ -903,7 +907,7 @@ t.test('first arg is a valid semver range', t => { } npm.flatOptions.diff = ['1.0.0', 'bar'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -918,7 +922,7 @@ t.test('first arg is a valid semver range', t => { }), }) - const diff = requireInject('../../lib/diff.js', { + const Diff = requireInject('../../lib/diff.js', { ...mocks, '../../lib/utils/read-local-package.js': async () => 'my-project', '@npmcli/arborist': class { @@ -931,11 +935,12 @@ t.test('first arg is a valid semver range', t => { t.equal(b, 'lorem@2.0.0', 'should target expected spec') }, }) + const diff = new Diff(npm) npm.flatOptions.diff = ['1.0.0', 'lorem@2.0.0'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -946,16 +951,17 @@ t.test('first arg is a valid semver range', t => { t.test('first arg is an unknown dependency name', t => { t.test('second arg is a qualified spec', t => { - t.plan(3) + t.plan(4) libnpmdiff = async ([a, b], opts) => { t.equal(a, 'bar@latest', 'should set expected first spec') t.equal(b, 'bar@2.0.0', 'should set expected second spec') t.match(opts, npm.flatOptions, 'should forward flat options') + t.match(opts, { where: '.' }, 'should forward pacote options') } npm.flatOptions.diff = ['bar', 'bar@2.0.0'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -989,7 +995,7 @@ t.test('first arg is an unknown dependency name', t => { npm.flatOptions.prefix = path npm.flatOptions.diff = ['bar-fork', 'bar'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -1004,7 +1010,7 @@ t.test('first arg is an unknown dependency name', t => { } npm.flatOptions.diff = ['bar', '^1.0.0'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -1019,7 +1025,7 @@ t.test('first arg is an unknown dependency name', t => { } npm.flatOptions.diff = ['bar', 'bar-fork'] - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -1040,7 +1046,7 @@ t.test('first arg is an unknown dependency name', t => { npm.flatOptions.diff = ['bar', 'bar-fork'] npm.flatOptions.prefix = path - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -1062,7 +1068,7 @@ t.test('various options', t => { }, 'should forward nameOnly=true option') } - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -1085,7 +1091,7 @@ t.test('various options', t => { }, 'should forward diffFiles values') } - diff(['./foo.js', './bar.js'], err => { + diff.exec(['./foo.js', './bar.js'], err => { if (err) throw err }) @@ -1109,7 +1115,7 @@ t.test('various options', t => { } npm.flatOptions.prefix = path - diff(['./foo.js', './bar.js'], err => { + diff.exec(['./foo.js', './bar.js'], err => { if (err) throw err }) @@ -1137,7 +1143,7 @@ t.test('various options', t => { }, 'should forward diff options') } - diff([], err => { + diff.exec([], err => { if (err) throw err }) @@ -1148,7 +1154,7 @@ t.test('various options', t => { t.test('too many args', t => { npm.flatOptions.diff = ['a', 'b', 'c'] - diff([], err => { + diff.exec([], err => { t.match( err, /Can't use more than two --diff arguments./, diff --git a/deps/npm/test/lib/dist-tag.js b/deps/npm/test/lib/dist-tag.js index c189352302..b761fb103c 100644 --- a/deps/npm/test/lib/dist-tag.js +++ b/deps/npm/test/lib/dist-tag.js @@ -48,7 +48,7 @@ const logger = (...msgs) => { log += '\n' } -const distTag = requireInject('../../lib/dist-tag.js', { +const DistTag = requireInject('../../lib/dist-tag.js', { npmlog: { error: logger, info: logger, @@ -58,26 +58,27 @@ const distTag = requireInject('../../lib/dist-tag.js', { get 'npm-registry-fetch' () { return npmRegistryFetchMock }, - '../../lib/npm.js': { - flatOptions: _flatOptions, - config: { - get (key) { - return _flatOptions[key] - }, - }, - }, '../../lib/utils/output.js': msg => { result = msg }, }) +const distTag = new DistTag({ + flatOptions: _flatOptions, + config: { + get (key) { + return _flatOptions[key] + }, + }, +}) + test('ls in current package', (t) => { prefix = t.testdir({ 'package.json': JSON.stringify({ name: '@scoped/pkg', }), }) - distTag(['ls'], (err) => { + distTag.exec(['ls'], (err) => { t.ifError(err, 'npm dist-tags ls') t.matchSnapshot( result, @@ -95,7 +96,7 @@ test('no args in current package', (t) => { name: '@scoped/pkg', }), }) - distTag([], (err) => { + distTag.exec([], (err) => { t.ifError(err, 'npm dist-tags ls') t.matchSnapshot( result, @@ -109,7 +110,7 @@ test('no args in current package', (t) => { test('borked cmd usage', (t) => { prefix = t.testdir({}) - distTag(['borked', '@scoped/pkg'], (err) => { + distTag.exec(['borked', '@scoped/pkg'], (err) => { t.matchSnapshot(err, 'should show usage error') result = '' log = '' @@ -119,7 +120,7 @@ test('borked cmd usage', (t) => { test('ls on named package', (t) => { prefix = t.testdir({}) - distTag(['ls', '@scoped/another'], (err) => { + distTag.exec(['ls', '@scoped/another'], (err) => { t.ifError(err, 'npm dist-tags ls') t.matchSnapshot( result, @@ -133,7 +134,7 @@ test('ls on named package', (t) => { test('ls on missing package', (t) => { prefix = t.testdir({}) - distTag(['ls', 'foo'], (err) => { + distTag.exec(['ls', 'foo'], (err) => { t.matchSnapshot( log, 'should log no dist-tag found msg' @@ -154,7 +155,7 @@ test('ls on missing name in current package', (t) => { version: '1.0.0', }), }) - distTag(['ls'], (err) => { + distTag.exec(['ls'], (err) => { t.matchSnapshot( err, 'should throw usage error message' @@ -167,7 +168,7 @@ test('ls on missing name in current package', (t) => { test('only named package arg', (t) => { prefix = t.testdir({}) - distTag(['@scoped/another'], (err) => { + distTag.exec(['@scoped/another'], (err) => { t.ifError(err, 'npm dist-tags ls') t.matchSnapshot( result, @@ -186,7 +187,7 @@ test('add new tag', (t) => { t.equal(opts.body, '7.7.7', 'should point to expected version') } prefix = t.testdir({}) - distTag(['add', '@scoped/another@7.7.7', 'c'], (err) => { + distTag.exec(['add', '@scoped/another@7.7.7', 'c'], (err) => { t.ifError(err, 'npm dist-tags add') t.matchSnapshot( result, @@ -201,7 +202,7 @@ test('add new tag', (t) => { test('add using valid semver range as name', (t) => { prefix = t.testdir({}) - distTag(['add', '@scoped/another@7.7.7', '1.0.0'], (err) => { + distTag.exec(['add', '@scoped/another@7.7.7', '1.0.0'], (err) => { t.match( err, /Error: Tag name must not be a valid SemVer range: 1.0.0/, @@ -219,7 +220,7 @@ test('add using valid semver range as name', (t) => { test('add missing args', (t) => { prefix = t.testdir({}) - distTag(['add', '@scoped/another@7.7.7'], (err) => { + distTag.exec(['add', '@scoped/another@7.7.7'], (err) => { t.matchSnapshot(err, 'should exit usage error message') result = '' log = '' @@ -229,7 +230,7 @@ test('add missing args', (t) => { test('add missing pkg name', (t) => { prefix = t.testdir({}) - distTag(['add', null], (err) => { + distTag.exec(['add', null], (err) => { t.matchSnapshot(err, 'should exit usage error message') result = '' log = '' @@ -239,7 +240,7 @@ test('add missing pkg name', (t) => { test('set existing version', (t) => { prefix = t.testdir({}) - distTag(['set', '@scoped/another@0.6.0', 'b'], (err) => { + distTag.exec(['set', '@scoped/another@0.6.0', 'b'], (err) => { t.ifError(err, 'npm dist-tags set') t.matchSnapshot( log, @@ -256,7 +257,7 @@ test('remove existing tag', (t) => { t.equal(opts.method, 'DELETE', 'should trigger request to remove tag') } prefix = t.testdir({}) - distTag(['rm', '@scoped/another', 'c'], (err) => { + distTag.exec(['rm', '@scoped/another', 'c'], (err) => { t.ifError(err, 'npm dist-tags rm') t.matchSnapshot(log, 'should log remove info') t.matchSnapshot(result, 'should return success msg') @@ -269,7 +270,7 @@ test('remove existing tag', (t) => { test('remove non-existing tag', (t) => { prefix = t.testdir({}) - distTag(['rm', '@scoped/another', 'nonexistent'], (err) => { + distTag.exec(['rm', '@scoped/another', 'nonexistent'], (err) => { t.match( err, /Error: nonexistent is not a dist-tag on @scoped\/another/, @@ -284,7 +285,7 @@ test('remove non-existing tag', (t) => { test('remove missing pkg name', (t) => { prefix = t.testdir({}) - distTag(['rm', null], (err) => { + distTag.exec(['rm', null], (err) => { t.matchSnapshot(err, 'should exit usage error message') result = '' log = '' diff --git a/deps/npm/test/lib/docs.js b/deps/npm/test/lib/docs.js index 8a59ed7cc0..a7325738ba 100644 --- a/deps/npm/test/lib/docs.js +++ b/deps/npm/test/lib/docs.js @@ -33,17 +33,18 @@ const pacote = { // keep a tally of which urls got opened const opened = {} -const openUrl = (url, errMsg, cb) => { +const openUrl = async (npm, url, errMsg) => { opened[url] = opened[url] || 0 opened[url]++ - process.nextTick(cb) } -const docs = requireInject('../../lib/docs.js', { +const Docs = requireInject('../../lib/docs.js', { pacote, '../../lib/utils/open-url.js': openUrl, }) +const docs = new Docs({ flatOptions: {} }) + t.test('open docs urls', t => { const expect = { nodocs: 'https://www.npmjs.com/package/nodocs', @@ -56,7 +57,7 @@ t.test('open docs urls', t => { t.plan(keys.length) keys.forEach(pkg => { t.test(pkg, t => { - docs([pkg], (er) => { + docs.exec([pkg], (er) => { if (er) throw er const url = expect[pkg] @@ -68,7 +69,7 @@ t.test('open docs urls', t => { }) t.test('open default package if none specified', t => { - docs([], (er) => { + docs.exec([], (er) => { if (er) throw er t.equal(opened['https://example.com'], 2, 'opened expected url', {opened}) diff --git a/deps/npm/test/lib/doctor.js b/deps/npm/test/lib/doctor.js index f5e6fd062a..eaa7ad72df 100644 --- a/deps/npm/test/lib/doctor.js +++ b/deps/npm/test/lib/doctor.js @@ -120,18 +120,18 @@ const cacache = { }, } -const doctor = requireInject('../../lib/doctor.js', { +const Doctor = requireInject('../../lib/doctor.js', { '../../lib/utils/is-windows.js': false, '../../lib/utils/ping.js': ping, '../../lib/utils/output.js': (data) => { output.push(data) }, - '../../lib/npm.js': npm, cacache, pacote, 'make-fetch-happen': fetch, which, }) +const doctor = new Doctor(npm) const origVersion = process.version test('node versions', t => { @@ -162,7 +162,7 @@ test('node versions', t => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { if (err) { st.fail(output) return st.end() @@ -211,7 +211,7 @@ test('node versions', t => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { if (err) { st.fail(err) return st.end() @@ -255,7 +255,7 @@ test('node versions', t => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { st.match(err, /Some problems found/, 'detected the ping error') st.match(logs, { checkPing: { finished: true }, @@ -282,18 +282,18 @@ test('node versions', t => { }) vt.test('npm doctor skips some tests in windows', st => { - const winDoctor = requireInject('../../lib/doctor.js', { + const WinDoctor = requireInject('../../lib/doctor.js', { '../../lib/utils/is-windows.js': true, '../../lib/utils/ping.js': ping, '../../lib/utils/output.js': (data) => { output.push(data) }, - '../../lib/npm.js': npm, cacache, pacote, 'make-fetch-happen': fetch, which, }) + const winDoctor = new WinDoctor(npm) const dir = st.testdir() npm.cache = npm.flatOptions.cache = dir @@ -312,7 +312,7 @@ test('node versions', t => { clearLogs() }) - winDoctor([], (err) => { + winDoctor.exec([], (err) => { if (err) { st.fail(output) return st.end() @@ -360,7 +360,7 @@ test('node versions', t => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { st.match(err, /Some problems found/, 'detected the ping error') st.match(logs, { checkPing: { finished: true }, @@ -409,7 +409,7 @@ test('node versions', t => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { st.match(err, /Some problems found/, 'detected the ping error') st.match(logs, { checkPing: { finished: true }, @@ -458,7 +458,7 @@ test('node versions', t => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { st.match(err, /Some problems found/, 'detected the out of date npm') st.match(logs, { checkPing: { finished: true }, @@ -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: {}, }, @@ -563,19 +563,19 @@ test('node versions', t => { } } - const doctor = requireInject('../../lib/doctor.js', { + const Doctor = requireInject('../../lib/doctor.js', { '../../lib/utils/is-windows.js': false, '../../lib/utils/ping.js': ping, '../../lib/utils/output.js': (data) => { output.push(data) }, - '../../lib/npm.js': npm, cacache, pacote, 'make-fetch-happen': fetch, which, fs, }) + const doctor = new Doctor(npm) // it's necessary to allow tests in node 10.x to not mark 12.x as lted npm.cache = npm.flatOptions.cache = join(dir, 'cache') @@ -600,7 +600,7 @@ test('node versions', t => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { st.match(err, /Some problems found/, 'identified problems') st.match(logs, { checkPing: { finished: true }, @@ -653,7 +653,7 @@ test('node versions', t => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { st.match(err, /Some problems found/, 'detected the missing git') st.match(logs, { checkPing: { finished: true }, @@ -706,7 +706,7 @@ test('node versions', t => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { // cache verification problems get fixed and so do not throw an error if (err) { st.fail(output) @@ -765,7 +765,7 @@ test('node versions', t => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { // cache verification problems get fixed and so do not throw an error if (err) { st.fail(output) @@ -823,7 +823,7 @@ test('node versions', t => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { // cache verification problems get fixed and so do not throw an error if (err) { st.fail(output) @@ -878,7 +878,7 @@ test('node versions', t => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { // cache verification problems get fixed and so do not throw an error st.match(err, /Some problems found/, 'detected the non-default registry') st.match(logs, { @@ -942,7 +942,7 @@ test('outdated node version', vt => { clearLogs() }) - doctor([], (err) => { + doctor.exec([], (err) => { st.match(err, /Some problems found/, 'detected the out of date nodejs') st.match(logs, { checkPing: { finished: true }, diff --git a/deps/npm/test/lib/edit.js b/deps/npm/test/lib/edit.js index 0d3bbb4c57..acf03fa438 100644 --- a/deps/npm/test/lib/edit.js +++ b/deps/npm/test/lib/edit.js @@ -23,6 +23,7 @@ const childProcess = { } let rebuildArgs = null +let rebuildFail = null let EDITOR = 'vim' const npm = { config: { @@ -32,17 +33,17 @@ const npm = { commands: { rebuild: (args, cb) => { rebuildArgs = args - return cb() + return cb(rebuildFail) }, }, } const gracefulFs = require('graceful-fs') -const edit = requireInject('../../lib/edit.js', { - '../../lib/npm.js': npm, +const Edit = requireInject('../../lib/edit.js', { child_process: childProcess, 'graceful-fs': gracefulFs, }) +const edit = new Edit(npm) test('npm edit', t => { t.teardown(() => { @@ -52,7 +53,7 @@ test('npm edit', t => { editorOpts = null }) - return edit(['semver'], (err) => { + return edit.exec(['semver'], (err) => { if (err) throw err @@ -65,6 +66,27 @@ test('npm edit', t => { }) }) +test('rebuild fails', t => { + t.teardown(() => { + rebuildFail = null + rebuildArgs = null + editorBin = null + editorArgs = null + editorOpts = null + }) + + rebuildFail = new Error('test error') + return edit.exec(['semver'], (err) => { + const path = resolve(__dirname, '../../node_modules/semver') + t.strictSame(editorBin, EDITOR, 'used the correct editor') + t.strictSame(editorArgs, [path], 'edited the correct directory') + t.strictSame(editorOpts, { stdio: 'inherit' }, 'passed the correct opts') + t.strictSame(rebuildArgs, [path], 'passed the correct path to rebuild') + t.match(err, { message: 'test error' }) + t.end() + }) +}) + test('npm edit editor has flags', t => { EDITOR = 'code -w' t.teardown(() => { @@ -75,7 +97,7 @@ test('npm edit editor has flags', t => { EDITOR = 'vim' }) - return edit(['semver'], (err) => { + return edit.exec(['semver'], (err) => { if (err) throw err @@ -89,7 +111,7 @@ test('npm edit editor has flags', t => { }) test('npm edit no args', t => { - return edit([], (err) => { + return edit.exec([], (err) => { t.match(err, /npm edit/, 'throws usage error') t.end() }) @@ -104,7 +126,7 @@ test('npm edit lstat error propagates', t => { gracefulFs.lstat = _lstat }) - return edit(['semver'], (err) => { + return edit.exec(['semver'], (err) => { t.match(err, /lstat failed/, 'user received correct error') t.end() }) @@ -116,7 +138,7 @@ test('npm edit editor exit code error propagates', t => { EDITOR_CODE = 0 }) - return edit(['semver'], (err) => { + return edit.exec(['semver'], (err) => { t.match(err, /exited with code: 137/, 'user received correct error') t.end() }) diff --git a/deps/npm/test/lib/exec.js b/deps/npm/test/lib/exec.js index ac813ade7b..4dc7f31cc3 100644 --- a/deps/npm/test/lib/exec.js +++ b/deps/npm/test/lib/exec.js @@ -90,13 +90,13 @@ const mocks = { '@npmcli/arborist': Arborist, '@npmcli/run-script': runScript, '@npmcli/ci-detect': () => CI_NAME, - '../../lib/npm.js': npm, pacote, read, 'mkdirp-infer-owner': mkdirp, '../../lib/utils/output.js': output, } -const exec = requireInject('../../lib/exec.js', mocks) +const Exec = requireInject('../../lib/exec.js', mocks) +const exec = new Exec(npm) t.afterEach(cb => { MKDIRPS.length = 0 @@ -116,7 +116,7 @@ t.afterEach(cb => { cb() }) -t.test('npx foo, bin already exists locally', async t => { +t.test('npx foo, bin already exists locally', t => { const path = t.testdir({ foo: 'just some file', }) @@ -124,24 +124,25 @@ t.test('npx foo, bin already exists locally', async t => { PROGRESS_IGNORED = true npm.localBin = path - await exec(['foo', 'one arg', 'two arg'], er => { + exec.exec(['foo', 'one arg', 'two arg'], er => { t.ifError(er, 'npm exec') + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'foo' }}, + args: ['one arg', 'two arg'], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { + PATH: [path, ...PATH].join(delimiter), + }, + stdio: 'inherit', + }]) + t.end() }) - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'foo' }}, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { - PATH: [path, ...PATH].join(delimiter), - }, - stdio: 'inherit', - }]) }) -t.test('npx foo, bin already exists globally', async t => { +t.test('npx foo, bin already exists globally', t => { const path = t.testdir({ foo: 'just some file', }) @@ -149,24 +150,25 @@ t.test('npx foo, bin already exists globally', async t => { PROGRESS_IGNORED = true npm.globalBin = path - await exec(['foo', 'one arg', 'two arg'], er => { + exec.exec(['foo', 'one arg', 'two arg'], er => { t.ifError(er, 'npm exec') + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'foo' }}, + args: ['one arg', 'two arg'], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { + PATH: [path, ...PATH].join(delimiter), + }, + stdio: 'inherit', + }]) + t.end() }) - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'foo' }}, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { - PATH: [path, ...PATH].join(delimiter), - }, - stdio: 'inherit', - }]) }) -t.test('npm exec foo, already present locally', async t => { +t.test('npm exec foo, already present locally', t => { const path = t.testdir() npm.localPrefix = path ARB_ACTUAL_TREE[path] = { @@ -180,94 +182,103 @@ t.test('npm exec foo, already present locally', async t => { }, _from: 'foo@', } - await exec(['foo', 'one arg', 'two arg'], er => { + exec.exec(['foo', 'one arg', 'two arg'], er => { if (er) throw er + t.strictSame(MKDIRPS, [], 'no need to make any dirs') + t.match(ARB_CTOR, [{ package: ['foo'], path }]) + t.strictSame(ARB_REIFY, [], 'no need to reify anything') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'foo' } }, + args: ['one arg', 'two arg'], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH: process.env.PATH }, + stdio: 'inherit', + }]) + t.end() }) - t.strictSame(MKDIRPS, [], 'no need to make any dirs') - t.match(ARB_CTOR, [{ package: ['foo'], path }]) - t.strictSame(ARB_REIFY, [], 'no need to reify anything') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH: process.env.PATH }, - stdio: 'inherit', - }]) }) -t.test('npm exec <noargs>, run interactive shell', async t => { +t.test('npm exec <noargs>, run interactive shell', t => { CI_NAME = null const { isTTY } = process.stdin process.stdin.isTTY = true t.teardown(() => process.stdin.isTTY = isTTY) - const run = async (t, doRun = true) => { + const run = (t, doRun, cb) => { LOG_WARN.length = 0 ARB_CTOR.length = 0 MKDIRPS.length = 0 ARB_REIFY.length = 0 OUTPUT.length = 0 - await exec([], er => { + exec.exec([], er => { if (er) throw er + t.strictSame(MKDIRPS, [], 'no need to make any dirs') + t.strictSame(ARB_CTOR, [], 'no need to instantiate arborist') + t.strictSame(ARB_REIFY, [], 'no need to reify anything') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + if (doRun) { + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'shell-cmd' } }, + args: [], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH: process.env.PATH }, + stdio: 'inherit', + }]) + } else + t.strictSame(RUN_SCRIPTS, []) + + RUN_SCRIPTS.length = 0 + cb() }) - t.strictSame(MKDIRPS, [], 'no need to make any dirs') - t.strictSame(ARB_CTOR, [], 'no need to instantiate arborist') - t.strictSame(ARB_REIFY, [], 'no need to reify anything') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - if (doRun) { - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'shell-cmd' } }, - args: [], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH: process.env.PATH }, - stdio: 'inherit', - }]) - } else - t.strictSame(RUN_SCRIPTS, []) - RUN_SCRIPTS.length = 0 } - t.test('print message when tty and not in CI', async t => { + t.test('print message when tty and not in CI', t => { CI_NAME = null process.stdin.isTTY = true - await run(t) - t.strictSame(LOG_WARN, []) - t.strictSame(OUTPUT, [ - ['\nEntering npm script environment\nType \'exit\' or ^D when finished\n'], - ], 'printed message about interactive shell') + run(t, true, () => { + t.strictSame(LOG_WARN, []) + t.strictSame(OUTPUT, [ + ['\nEntering npm script environment\nType \'exit\' or ^D when finished\n'], + ], 'printed message about interactive shell') + t.end() + }) }) - t.test('no message when not TTY', async t => { + t.test('no message when not TTY', t => { CI_NAME = null process.stdin.isTTY = false - await run(t) - t.strictSame(LOG_WARN, []) - t.strictSame(OUTPUT, [], 'no message about interactive shell') + run(t, true, () => { + t.strictSame(LOG_WARN, []) + t.strictSame(OUTPUT, [], 'no message about interactive shell') + t.end() + }) }) - t.test('print warning when in CI and interactive', async t => { + t.test('print warning when in CI and interactive', t => { CI_NAME = 'travis-ci' process.stdin.isTTY = true - await run(t, false) - t.strictSame(LOG_WARN, [ - ['exec', 'Interactive mode disabled in CI environment'], - ]) - t.strictSame(OUTPUT, [], 'no message about interactive shell') + run(t, false, () => { + t.strictSame(LOG_WARN, [ + ['exec', 'Interactive mode disabled in CI environment'], + ]) + t.strictSame(OUTPUT, [], 'no message about interactive shell') + t.end() + }) }) t.end() }) -t.test('npm exec foo, not present locally or in central loc', async t => { +t.test('npm exec foo, not present locally or in central loc', t => { const path = t.testdir() const installDir = resolve('cache-dir/_npx/f7fbba6e0636f890') npm.localPrefix = path @@ -285,28 +296,29 @@ t.test('npm exec foo, not present locally or in central loc', async t => { }, _from: 'foo@', } - await exec(['foo', 'one arg', 'two arg'], er => { + exec.exec(['foo', 'one arg', 'two arg'], er => { if (er) throw er + t.strictSame(MKDIRPS, [installDir], 'need to make install dir') + t.match(ARB_CTOR, [{ package: ['foo'], path }]) + t.match(ARB_REIFY, [{add: ['foo@'], legacyPeerDeps: false}], 'need to install foo@') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'foo' } }, + args: ['one arg', 'two arg'], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH }, + stdio: 'inherit', + }]) + t.end() }) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ package: ['foo'], path }]) - t.match(ARB_REIFY, [{add: ['foo@'], legacyPeerDeps: false}], 'need to install foo@') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }]) }) -t.test('npm exec foo, not present locally but in central loc', async t => { +t.test('npm exec foo, not present locally but in central loc', t => { const path = t.testdir() const installDir = resolve('cache-dir/_npx/f7fbba6e0636f890') npm.localPrefix = path @@ -324,28 +336,29 @@ t.test('npm exec foo, not present locally but in central loc', async t => { }, _from: 'foo@', } - await exec(['foo', 'one arg', 'two arg'], er => { + exec.exec(['foo', 'one arg', 'two arg'], er => { if (er) throw er + t.strictSame(MKDIRPS, [installDir], 'need to make install dir') + t.match(ARB_CTOR, [{ package: ['foo'], path }]) + t.match(ARB_REIFY, [], 'no need to install again, already there') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'foo' } }, + args: ['one arg', 'two arg'], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH }, + stdio: 'inherit', + }]) + t.end() }) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ package: ['foo'], path }]) - t.match(ARB_REIFY, [], 'no need to install again, already there') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }]) }) -t.test('npm exec foo, present locally but wrong version', async t => { +t.test('npm exec foo, present locally but wrong version', t => { const path = t.testdir() const installDir = resolve('cache-dir/_npx/2badf4630f1cfaad') npm.localPrefix = path @@ -363,28 +376,29 @@ t.test('npm exec foo, present locally but wrong version', async t => { }, _from: 'foo@2.x', } - await exec(['foo@2.x', 'one arg', 'two arg'], er => { + exec.exec(['foo@2.x', 'one arg', 'two arg'], er => { if (er) throw er + t.strictSame(MKDIRPS, [installDir], 'need to make install dir') + t.match(ARB_CTOR, [{ package: ['foo'], path }]) + t.match(ARB_REIFY, [{ add: ['foo@2.x'], legacyPeerDeps: false }], 'need to add foo@2.x') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'foo' } }, + args: ['one arg', 'two arg'], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH }, + stdio: 'inherit', + }]) + t.end() }) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ package: ['foo'], path }]) - t.match(ARB_REIFY, [{ add: ['foo@2.x'], legacyPeerDeps: false }], 'need to add foo@2.x') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }]) }) -t.test('npm exec --package=foo bar', async t => { +t.test('npm exec --package=foo bar', t => { const path = t.testdir() npm.localPrefix = path ARB_ACTUAL_TREE[path] = { @@ -399,27 +413,28 @@ t.test('npm exec --package=foo bar', async t => { _from: 'foo@', } npm.flatOptions.package = ['foo'] - await exec(['bar', 'one arg', 'two arg'], er => { + exec.exec(['bar', 'one arg', 'two arg'], er => { if (er) throw er + t.strictSame(MKDIRPS, [], 'no need to make any dirs') + t.match(ARB_CTOR, [{ package: ['foo'], path }]) + t.strictSame(ARB_REIFY, [], 'no need to reify anything') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'bar' } }, + args: ['one arg', 'two arg'], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH: process.env.PATH }, + stdio: 'inherit', + }]) + t.end() }) - t.strictSame(MKDIRPS, [], 'no need to make any dirs') - t.match(ARB_CTOR, [{ package: ['foo'], path }]) - t.strictSame(ARB_REIFY, [], 'no need to reify anything') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'bar' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH: process.env.PATH }, - stdio: 'inherit', - }]) }) -t.test('npm exec @foo/bar -- --some=arg, locally installed', async t => { +t.test('npm exec @foo/bar -- --some=arg, locally installed', t => { const foobarManifest = { name: '@foo/bar', version: '1.2.3', @@ -440,27 +455,28 @@ t.test('npm exec @foo/bar -- --some=arg, locally installed', async t => { children: new Map([['@foo/bar', { name: '@foo/bar', version: '1.2.3' }]]), } MANIFESTS['@foo/bar'] = foobarManifest - await exec(['@foo/bar', '--some=arg'], er => { + exec.exec(['@foo/bar', '--some=arg'], er => { if (er) throw er + t.strictSame(MKDIRPS, [], 'no need to make any dirs') + t.match(ARB_CTOR, [{ package: ['@foo/bar'], path }]) + t.strictSame(ARB_REIFY, [], 'no need to reify anything') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'bar' } }, + args: ['--some=arg'], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH: process.env.PATH }, + stdio: 'inherit', + }]) + t.end() }) - t.strictSame(MKDIRPS, [], 'no need to make any dirs') - t.match(ARB_CTOR, [{ package: ['@foo/bar'], path }]) - t.strictSame(ARB_REIFY, [], 'no need to reify anything') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'bar' } }, - args: ['--some=arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH: process.env.PATH }, - stdio: 'inherit', - }]) }) -t.test('npm exec @foo/bar, with same bin alias and no unscoped named bin, locally installed', async t => { +t.test('npm exec @foo/bar, with same bin alias and no unscoped named bin, locally installed', t => { const foobarManifest = { name: '@foo/bar', version: '1.2.3', @@ -482,24 +498,25 @@ t.test('npm exec @foo/bar, with same bin alias and no unscoped named bin, locall children: new Map([['@foo/bar', { name: '@foo/bar', version: '1.2.3' }]]), } MANIFESTS['@foo/bar'] = foobarManifest - await exec(['@foo/bar', 'one arg', 'two arg'], er => { + exec.exec(['@foo/bar', 'one arg', 'two arg'], er => { if (er) throw er + t.strictSame(MKDIRPS, [], 'no need to make any dirs') + t.match(ARB_CTOR, [{ package: ['@foo/bar'], path }]) + t.strictSame(ARB_REIFY, [], 'no need to reify anything') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'baz' } }, + args: ['one arg', 'two arg'], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH: process.env.PATH }, + stdio: 'inherit', + }]) + t.end() }) - t.strictSame(MKDIRPS, [], 'no need to make any dirs') - t.match(ARB_CTOR, [{ package: ['@foo/bar'], path }]) - t.strictSame(ARB_REIFY, [], 'no need to reify anything') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'baz' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH: process.env.PATH }, - stdio: 'inherit', - }]) }) t.test('npm exec @foo/bar, with different bin alias and no unscoped named bin, locally installed', t => { @@ -519,12 +536,12 @@ t.test('npm exec @foo/bar, with different bin alias and no unscoped named bin, l _from: 'foo@', _id: '@foo/bar@1.2.3', } - return t.rejects(exec(['@foo/bar'], er => { - if (er) - throw er - }), { - message: 'could not determine executable to run', - pkgid: '@foo/bar@1.2.3', + exec.exec(['@foo/bar'], er => { + t.match(er, { + message: 'could not determine executable to run', + pkgid: '@foo/bar@1.2.3', + }) + t.end() }) }) @@ -534,7 +551,7 @@ t.test('run command with 2 packages, need install, verify sort', t => { const cases = [['foo', 'bar'], ['bar', 'foo']] t.plan(cases.length) for (const packages of cases) { - t.test(packages.join(', '), async t => { + t.test(packages.join(', '), t => { npm.flatOptions.package = packages const add = packages.map(p => `${p}@`).sort((a, b) => a.localeCompare(b)) const path = t.testdir() @@ -562,25 +579,26 @@ t.test('run command with 2 packages, need install, verify sort', t => { }, _from: 'bar@', } - await exec(['foobar', 'one arg', 'two arg'], er => { + exec.exec(['foobar', 'one arg', 'two arg'], er => { if (er) throw er + t.strictSame(MKDIRPS, [installDir], 'need to make install dir') + t.match(ARB_CTOR, [{ package: packages, path }]) + t.match(ARB_REIFY, [{add, legacyPeerDeps: false}], 'need to install both packages') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'foobar' } }, + args: ['one arg', 'two arg'], + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH }, + stdio: 'inherit', + }]) + t.end() }) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ package: packages, path }]) - t.match(ARB_REIFY, [{add, legacyPeerDeps: false}], 'need to install both packages') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'foobar' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }]) }) } }) @@ -597,12 +615,12 @@ t.test('npm exec foo, no bin in package', t => { _from: 'foo@', _id: 'foo@1.2.3', } - return t.rejects(exec(['foo'], er => { - if (er) - throw er - }), { - message: 'could not determine executable to run', - pkgid: 'foo@1.2.3', + exec.exec(['foo'], er => { + t.match(er, { + message: 'could not determine executable to run', + pkgid: 'foo@1.2.3', + }) + t.end() }) }) @@ -622,16 +640,16 @@ t.test('npm exec foo, many bins in package, none named foo', t => { _from: 'foo@', _id: 'foo@1.2.3', } - return t.rejects(exec(['foo'], er => { - if (er) - throw er - }), { - message: 'could not determine executable to run', - pkgid: 'foo@1.2.3', + exec.exec(['foo'], er => { + t.match(er, { + message: 'could not determine executable to run', + pkgid: 'foo@1.2.3', + }) + t.end() }) }) -t.test('npm exec -p foo -c "ls -laF"', async t => { +t.test('npm exec -p foo -c "ls -laF"', t => { const path = t.testdir() npm.localPrefix = path npm.flatOptions.package = ['foo'] @@ -644,31 +662,35 @@ t.test('npm exec -p foo -c "ls -laF"', async t => { version: '1.2.3', _from: 'foo@', } - await exec([], er => { + exec.exec([], er => { if (er) throw er + t.strictSame(MKDIRPS, [], 'no need to make any dirs') + t.match(ARB_CTOR, [{ package: ['foo'], path }]) + t.strictSame(ARB_REIFY, [], 'no need to reify anything') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'ls -laF' } }, + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH: process.env.PATH }, + stdio: 'inherit', + }]) + t.end() }) - t.strictSame(MKDIRPS, [], 'no need to make any dirs') - t.match(ARB_CTOR, [{ package: ['foo'], path }]) - t.strictSame(ARB_REIFY, [], 'no need to reify anything') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'ls -laF' } }, - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH: process.env.PATH }, - stdio: 'inherit', - }]) }) t.test('positional args and --call together is an error', t => { npm.flatOptions.call = 'true' - return exec(['foo'], er => t.equal(er, exec.usage)) + exec.exec(['foo'], er => { + t.equal(er, exec.usage) + t.end() + }) }) -t.test('prompt when installs are needed if not already present and shell is a TTY', async t => { +t.test('prompt when installs are needed if not already present and shell is a TTY', t => { const stdoutTTY = process.stdout.isTTY const stdinTTY = process.stdin.isTTY t.teardown(() => { @@ -712,31 +734,32 @@ t.test('prompt when installs are needed if not already present and shell is a TT }, _from: 'bar@', } - await exec(['foobar'], er => { + exec.exec(['foobar'], er => { if (er) throw er + t.strictSame(MKDIRPS, [installDir], 'need to make install dir') + t.match(ARB_CTOR, [{ package: packages, path }]) + t.match(ARB_REIFY, [{add, legacyPeerDeps: false}], 'need to install both packages') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'foobar' } }, + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH }, + stdio: 'inherit', + }]) + t.strictSame(READ, [{ + prompt: 'Need to install the following packages:\n bar\n foo\nOk to proceed? ', + default: 'y', + }]) + t.end() }) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ package: packages, path }]) - t.match(ARB_REIFY, [{add, legacyPeerDeps: false}], 'need to install both packages') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'foobar' } }, - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }]) - t.strictSame(READ, [{ - prompt: 'Need to install the following packages:\n bar\n foo\nOk to proceed? ', - default: 'y', - }]) }) -t.test('skip prompt when installs are needed if not already present and shell is not a tty (multiple packages)', async t => { +t.test('skip prompt when installs are needed if not already present and shell is not a tty (multiple packages)', t => { const stdoutTTY = process.stdout.isTTY const stdinTTY = process.stdin.isTTY t.teardown(() => { @@ -780,29 +803,30 @@ t.test('skip prompt when installs are needed if not already present and shell is }, _from: 'bar@', } - await exec(['foobar'], er => { + exec.exec(['foobar'], er => { if (er) throw er + t.strictSame(MKDIRPS, [installDir], 'need to make install dir') + t.match(ARB_CTOR, [{ package: packages, path }]) + t.match(ARB_REIFY, [{add, legacyPeerDeps: false}], 'need to install both packages') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'foobar' } }, + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH }, + stdio: 'inherit', + }]) + t.strictSame(READ, [], 'should not have prompted') + t.strictSame(LOG_WARN, [['exec', 'The following packages were not found and will be installed: bar, foo']], 'should have printed a warning') + t.end() }) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ package: packages, path }]) - t.match(ARB_REIFY, [{add, legacyPeerDeps: false}], 'need to install both packages') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'foobar' } }, - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }]) - t.strictSame(READ, [], 'should not have prompted') - t.strictSame(LOG_WARN, [['exec', 'The following packages were not found and will be installed: bar, foo']], 'should have printed a warning') }) -t.test('skip prompt when installs are needed if not already present and shell is not a tty (single package)', async t => { +t.test('skip prompt when installs are needed if not already present and shell is not a tty (single package)', t => { const stdoutTTY = process.stdout.isTTY const stdinTTY = process.stdin.isTTY t.teardown(() => { @@ -838,29 +862,30 @@ t.test('skip prompt when installs are needed if not already present and shell is }, _from: 'foo@', } - await exec(['foobar'], er => { + exec.exec(['foobar'], er => { if (er) throw er + t.strictSame(MKDIRPS, [installDir], 'need to make install dir') + t.match(ARB_CTOR, [{ package: packages, path }]) + t.match(ARB_REIFY, [{add, legacyPeerDeps: false}], 'need to install the package') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` + t.match(RUN_SCRIPTS, [{ + pkg: { scripts: { npx: 'foobar' } }, + banner: false, + path: process.cwd(), + stdioString: true, + event: 'npx', + env: { PATH }, + stdio: 'inherit', + }]) + t.strictSame(READ, [], 'should not have prompted') + t.strictSame(LOG_WARN, [['exec', 'The following package was not found and will be installed: foo']], 'should have printed a warning') + t.end() }) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ package: packages, path }]) - t.match(ARB_REIFY, [{add, legacyPeerDeps: false}], 'need to install the package') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [{ - pkg: { scripts: { npx: 'foobar' } }, - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }]) - t.strictSame(READ, [], 'should not have prompted') - t.strictSame(LOG_WARN, [['exec', 'The following package was not found and will be installed: foo']], 'should have printed a warning') }) -t.test('abort if prompt rejected', async t => { +t.test('abort if prompt rejected', t => { const stdoutTTY = process.stdout.isTTY const stdinTTY = process.stdin.isTTY t.teardown(() => { @@ -903,21 +928,22 @@ t.test('abort if prompt rejected', async t => { }, _from: 'bar@', } - await exec(['foobar'], er => { + exec.exec(['foobar'], er => { t.equal(er, 'canceled', 'should be canceled') + t.strictSame(MKDIRPS, [installDir], 'need to make install dir') + t.match(ARB_CTOR, [{ package: packages, path }]) + t.strictSame(ARB_REIFY, [], 'no install performed') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + t.strictSame(RUN_SCRIPTS, []) + t.strictSame(READ, [{ + prompt: 'Need to install the following packages:\n bar\n foo\nOk to proceed? ', + default: 'y', + }]) + t.end() }) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ package: packages, path }]) - t.strictSame(ARB_REIFY, [], 'no install performed') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.strictSame(RUN_SCRIPTS, []) - t.strictSame(READ, [{ - prompt: 'Need to install the following packages:\n bar\n foo\nOk to proceed? ', - default: 'y', - }]) }) -t.test('abort if prompt false', async t => { +t.test('abort if prompt false', t => { const stdoutTTY = process.stdout.isTTY const stdinTTY = process.stdin.isTTY t.teardown(() => { @@ -960,21 +986,22 @@ t.test('abort if prompt false', async t => { }, _from: 'bar@', } - await exec(['foobar'], er => { + exec.exec(['foobar'], er => { t.equal(er, 'canceled', 'should be canceled') + t.strictSame(MKDIRPS, [installDir], 'need to make install dir') + t.match(ARB_CTOR, [{ package: packages, path }]) + t.strictSame(ARB_REIFY, [], 'no install performed') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + t.strictSame(RUN_SCRIPTS, []) + t.strictSame(READ, [{ + prompt: 'Need to install the following packages:\n bar\n foo\nOk to proceed? ', + default: 'y', + }]) + t.end() }) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ package: packages, path }]) - t.strictSame(ARB_REIFY, [], 'no install performed') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.strictSame(RUN_SCRIPTS, []) - t.strictSame(READ, [{ - prompt: 'Need to install the following packages:\n bar\n foo\nOk to proceed? ', - default: 'y', - }]) }) -t.test('abort if -n provided', async t => { +t.test('abort if -n provided', t => { const stdoutTTY = process.stdout.isTTY const stdinTTY = process.stdin.isTTY t.teardown(() => { @@ -1016,18 +1043,19 @@ t.test('abort if -n provided', async t => { }, _from: 'bar@', } - await exec(['foobar'], er => { + exec.exec(['foobar'], er => { t.equal(er, 'canceled', 'should be canceled') + t.strictSame(MKDIRPS, [installDir], 'need to make install dir') + t.match(ARB_CTOR, [{ package: packages, path }]) + t.strictSame(ARB_REIFY, [], 'no install performed') + t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') + t.strictSame(RUN_SCRIPTS, []) + t.strictSame(READ, []) + t.done() }) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ package: packages, path }]) - t.strictSame(ARB_REIFY, [], 'no install performed') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.strictSame(RUN_SCRIPTS, []) - t.strictSame(READ, []) }) -t.test('forward legacyPeerDeps opt', async t => { +t.test('forward legacyPeerDeps opt', t => { const path = t.testdir() const installDir = resolve('cache-dir/_npx/f7fbba6e0636f890') npm.localPrefix = path @@ -1047,9 +1075,10 @@ t.test('forward legacyPeerDeps opt', async t => { } npm.flatOptions.yes = true npm.flatOptions.legacyPeerDeps = true - await exec(['foo'], er => { + exec.exec(['foo'], er => { if (er) throw er + t.match(ARB_REIFY, [{add: ['foo@'], legacyPeerDeps: true}], 'need to install foo@ using legacyPeerDeps opt') + t.done() }) - t.match(ARB_REIFY, [{add: ['foo@'], legacyPeerDeps: true}], 'need to install foo@ using legacyPeerDeps opt') }) diff --git a/deps/npm/test/lib/explain.js b/deps/npm/test/lib/explain.js index 1eeca8c4c4..22bfb8639e 100644 --- a/deps/npm/test/lib/explain.js +++ b/deps/npm/test/lib/explain.js @@ -9,9 +9,7 @@ const { resolve } = require('path') const OUTPUT = [] -const explain = requireInject('../../lib/explain.js', { - '../../lib/npm.js': npm, - +const Explain = requireInject('../../lib/explain.js', { '../../lib/utils/output.js': (...args) => { OUTPUT.push(args) }, @@ -23,44 +21,40 @@ const explain = requireInject('../../lib/explain.js', { }, }, }) +const explain = new Explain(npm) -t.test('no args throws usage', async t => { +t.test('no args throws usage', t => { t.plan(1) - try { - await explain([], er => { - throw er - }) - } catch (er) { + explain.exec([], er => { t.equal(er, explain.usage) - } + t.done() + }) }) -t.test('no match throws not found', async t => { +t.test('no match throws not found', t => { npm.prefix = t.testdir() t.plan(1) - try { - await explain(['foo@1.2.3', 'node_modules/baz'], er => { - throw er - }) - } catch (er) { + explain.exec(['foo@1.2.3', 'node_modules/baz'], er => { t.equal(er, 'No dependencies found matching foo@1.2.3, node_modules/baz') - } + }) }) -t.test('invalid package name throws not found', async t => { +t.test('invalid package name throws not found', t => { npm.prefix = t.testdir() t.plan(1) const badName = ' not a valid package name ' - try { - await explain([`${badName}@1.2.3`], er => { - throw er - }) - } catch (er) { + explain.exec([`${badName}@1.2.3`], er => { t.equal(er, `No dependencies found matching ${badName}@1.2.3`) - } + }) }) -t.test('explain some nodes', async t => { +t.test('explain some nodes', t => { + t.afterEach((cb) => { + OUTPUT.length = 0 + npm.flatOptions.json = false + cb() + }) + npm.prefix = t.testdir({ node_modules: { foo: { @@ -111,61 +105,75 @@ t.test('explain some nodes', async t => { }), }) - // works with either a full actual path or the location - const p = 'node_modules/foo' - for (const path of [p, resolve(npm.prefix, p)]) { - await explain([path], er => { + t.test('works with the location', t => { + const path = 'node_modules/foo' + explain.exec([path], er => { if (er) throw er + t.strictSame(OUTPUT, [['foo@1.2.3 depth=Infinity color=true']]) + t.end() }) - t.strictSame(OUTPUT, [['foo@1.2.3 depth=Infinity color=true']]) - OUTPUT.length = 0 - } + }) + t.test('works with a full actual path', t => { + const path = resolve(npm.prefix, 'node_modules/foo') + explain.exec([path], er => { + if (er) + throw er + t.strictSame(OUTPUT, [['foo@1.2.3 depth=Infinity color=true']]) + t.end() + }) + }) - // finds all nodes by name - await explain(['bar'], er => { - if (er) - throw er + t.test('finds all nodes by name', t => { + explain.exec(['bar'], er => { + if (er) + throw er + t.strictSame(OUTPUT, [[ + 'bar@1.2.3 depth=Infinity color=true\n\n' + + 'bar@2.3.4 depth=Infinity color=true', + ]]) + t.end() + }) }) - t.strictSame(OUTPUT, [[ - 'bar@1.2.3 depth=Infinity color=true\n\n' + - 'bar@2.3.4 depth=Infinity color=true', - ]]) - OUTPUT.length = 0 - // finds only nodes that match the spec - await explain(['bar@1'], er => { - if (er) - throw er + t.test('finds only nodes that match the spec', t => { + explain.exec(['bar@1'], er => { + if (er) + throw er + t.strictSame(OUTPUT, [['bar@1.2.3 depth=Infinity color=true']]) + t.end() + }) }) - t.strictSame(OUTPUT, [['bar@1.2.3 depth=Infinity color=true']]) - OUTPUT.length = 0 - // finds extraneous nodes - await explain(['extra'], er => { - if (er) - throw er + t.test('finds extraneous nodes', t => { + explain.exec(['extra'], er => { + if (er) + throw er + t.strictSame(OUTPUT, [['extra@99.9999.999999 depth=Infinity color=true']]) + t.end() + }) }) - t.strictSame(OUTPUT, [['extra@99.9999.999999 depth=Infinity color=true']]) - OUTPUT.length = 0 - npm.flatOptions.json = true - await explain(['node_modules/foo'], er => { - if (er) - throw er + t.test('json output', t => { + npm.flatOptions.json = true + explain.exec(['node_modules/foo'], er => { + if (er) + throw er + t.match(JSON.parse(OUTPUT[0][0]), [{ + name: 'foo', + version: '1.2.3', + dependents: Array, + }]) + t.end() + }) }) - t.match(JSON.parse(OUTPUT[0][0]), [{ - name: 'foo', - version: '1.2.3', - dependents: Array, - }]) - OUTPUT.length = 0 - npm.flatOptions.json = false - t.test('report if no nodes found', async t => { + t.test('report if no nodes found', t => { t.plan(1) - await explain(['asdf/foo/bar', 'quux@1.x'], er => { + explain.exec(['asdf/foo/bar', 'quux@1.x'], er => { t.equal(er, 'No dependencies found matching asdf/foo/bar, quux@1.x') + t.done() }) }) + t.end() }) diff --git a/deps/npm/test/lib/explore.js b/deps/npm/test/lib/explore.js index 23eab1172a..6f1f3bb47f 100644 --- a/deps/npm/test/lib/explore.js +++ b/deps/npm/test/lib/explore.js @@ -46,14 +46,20 @@ const mockRunScript = ({ pkg, banner, path, event, stdio }) => { const output = [] let ERROR_HANDLER_CALLED = null const logs = [] -const getExplore = windows => requireInject('../../lib/explore.js', { - '../../lib/utils/is-windows.js': windows, - path: require('path')[windows ? 'win32' : 'posix'], - '../../lib/utils/error-handler.js': er => { - ERROR_HANDLER_CALLED = er - }, - 'read-package-json-fast': mockRPJ, - '../../lib/npm.js': { +const getExplore = (windows) => { + const Explore = requireInject('../../lib/explore.js', { + '../../lib/utils/is-windows.js': windows, + path: require('path')[windows ? 'win32' : 'posix'], + '../../lib/utils/error-handler.js': er => { + ERROR_HANDLER_CALLED = er + }, + 'read-package-json-fast': mockRPJ, + '@npmcli/run-script': mockRunScript, + '../../lib/utils/output.js': out => { + output.push(out) + }, + }) + const npm = { dir: windows ? 'c:\\npm\\dir' : '/npm/dir', log: { error: (...msg) => logs.push(msg), @@ -63,12 +69,9 @@ const getExplore = windows => requireInject('../../lib/explore.js', { flatOptions: { shell: 'shell-command', }, - }, - '@npmcli/run-script': mockRunScript, - '../../lib/utils/output.js': out => { - output.push(out) - }, -}) + } + return new Explore(npm) +} const windowsExplore = getExplore(true) const posixExplore = getExplore(false) @@ -79,7 +82,7 @@ t.test('basic interactive', t => { cb() }) - t.test('windows', t => windowsExplore(['pkg'], er => { + t.test('windows', t => windowsExplore.exec(['pkg'], er => { if (er) throw er @@ -95,9 +98,10 @@ t.test('basic interactive', t => { t.strictSame(output, [ "\nExploring c:\\npm\\dir\\pkg\nType 'exit' or ^D when finished\n", ]) + t.end() })) - t.test('posix', t => posixExplore(['pkg'], er => { + t.test('posix', t => posixExplore.exec(['pkg'], er => { if (er) throw er @@ -113,6 +117,7 @@ t.test('basic interactive', t => { t.strictSame(output, [ "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n", ]) + t.end() })) t.end() @@ -132,7 +137,7 @@ t.test('interactive tracks exit code', t => { cb() }) - t.test('windows', t => windowsExplore(['pkg'], er => { + t.test('windows', t => windowsExplore.exec(['pkg'], er => { if (er) throw er @@ -149,9 +154,10 @@ t.test('interactive tracks exit code', t => { "\nExploring c:\\npm\\dir\\pkg\nType 'exit' or ^D when finished\n", ]) t.equal(process.exitCode, 99) + t.end() })) - t.test('posix', t => posixExplore(['pkg'], er => { + t.test('posix', t => posixExplore.exec(['pkg'], er => { if (er) throw er @@ -168,18 +174,20 @@ t.test('interactive tracks exit code', t => { "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n", ]) t.equal(process.exitCode, 99) + t.end() })) t.test('posix spawn fail', t => { RUN_SCRIPT_ERROR = Object.assign(new Error('glorb'), { code: 33, }) - return posixExplore(['pkg'], er => { + posixExplore.exec(['pkg'], er => { t.match(er, { message: 'glorb', code: 33 }) t.strictSame(output, [ "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n", ]) t.equal(process.exitCode, 33) + t.end() }) }) @@ -187,12 +195,13 @@ t.test('interactive tracks exit code', t => { RUN_SCRIPT_ERROR = Object.assign(new Error('glorb'), { code: 0, }) - return posixExplore(['pkg'], er => { + posixExplore.exec(['pkg'], er => { t.match(er, { message: 'glorb', code: 0 }) t.strictSame(output, [ "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n", ]) t.equal(process.exitCode, 1) + t.end() }) }) @@ -200,12 +209,13 @@ t.test('interactive tracks exit code', t => { RUN_SCRIPT_ERROR = Object.assign(new Error('command failed'), { code: 'EPROBLEM', }) - return posixExplore(['pkg'], er => { + posixExplore.exec(['pkg'], er => { t.match(er, { message: 'command failed', code: 'EPROBLEM' }) t.strictSame(output, [ "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n", ]) t.equal(process.exitCode, 1) + t.end() }) }) @@ -218,7 +228,7 @@ t.test('basic non-interactive', t => { cb() }) - t.test('windows', t => windowsExplore(['pkg', 'ls'], er => { + t.test('windows', t => windowsExplore.exec(['pkg', 'ls'], er => { if (er) throw er @@ -232,9 +242,10 @@ t.test('basic non-interactive', t => { RUN_SCRIPT_EXEC: 'ls', }) t.strictSame(output, []) + t.end() })) - t.test('posix', t => posixExplore(['pkg', 'ls'], er => { + t.test('posix', t => posixExplore.exec(['pkg', 'ls'], er => { if (er) throw er @@ -248,6 +259,7 @@ t.test('basic non-interactive', t => { RUN_SCRIPT_EXEC: 'ls', }) t.strictSame(output, []) + t.end() })) t.end() @@ -272,7 +284,7 @@ t.test('signal fails non-interactive', t => { cb() }) - t.test('windows', t => windowsExplore(['pkg', 'ls'], er => { + t.test('windows', t => windowsExplore.exec(['pkg', 'ls'], er => { t.match(er, { message: 'command failed', signal: 'SIGPROBLEM', @@ -286,9 +298,10 @@ t.test('signal fails non-interactive', t => { RUN_SCRIPT_EXEC: 'ls', }) t.strictSame(output, []) + t.end() })) - t.test('posix', t => posixExplore(['pkg', 'ls'], er => { + t.test('posix', t => posixExplore.exec(['pkg', 'ls'], er => { t.match(er, { message: 'command failed', signal: 'SIGPROBLEM', @@ -302,6 +315,7 @@ t.test('signal fails non-interactive', t => { RUN_SCRIPT_EXEC: 'ls', }) t.strictSame(output, []) + t.end() })) t.end() @@ -322,29 +336,28 @@ t.test('usage if no pkg provided', t => { ] t.plan(noPkg.length) for (const args of noPkg) { - t.test(JSON.stringify(args), t => posixExplore(args, er => { - t.equal(er, 'npm explore <pkg> [ -- <command>]') - t.strictSame({ - ERROR_HANDLER_CALLED: null, - RPJ_CALLED, - RUN_SCRIPT_EXEC, - }, { - ERROR_HANDLER_CALLED: null, - RPJ_CALLED: '/npm/dir/pkg/package.json', - RUN_SCRIPT_EXEC: 'ls', + t.test(JSON.stringify(args), t => { + posixExplore.exec(args, er => { + t.equal(er, 'npm explore <pkg> [ -- <command>]') + t.strictSame({ + ERROR_HANDLER_CALLED: null, + RPJ_CALLED, + RUN_SCRIPT_EXEC, + }, { + ERROR_HANDLER_CALLED: null, + RPJ_CALLED: '/npm/dir/pkg/package.json', + RUN_SCRIPT_EXEC: 'ls', + }) + t.end() }) - })) + }) } }) t.test('pkg not installed', t => { RPJ_ERROR = new Error('plurple') - t.plan(2) - - posixExplore(['pkg', 'ls'], er => { - if (er) - throw er + posixExplore.exec(['pkg', 'ls'], er => { t.strictSame({ ERROR_HANDLER_CALLED, RPJ_CALLED, @@ -355,9 +368,9 @@ t.test('pkg not installed', t => { RUN_SCRIPT_EXEC: 'ls', }) t.strictSame(output, []) - }).catch(er => { t.match(er, { message: 'plurple' }) t.match(logs, [['explore', `It doesn't look like pkg is installed.`]]) + t.end() logs.length = 0 }) }) diff --git a/deps/npm/test/lib/find-dupes.js b/deps/npm/test/lib/find-dupes.js index 73c8fa2dc2..c7b33ceb6e 100644 --- a/deps/npm/test/lib/find-dupes.js +++ b/deps/npm/test/lib/find-dupes.js @@ -1,15 +1,24 @@ -const { test } = require('tap') -const requireInject = require('require-inject') +const t = require('tap') -test('should run dedupe in dryRun mode', (t) => { - const findDupes = requireInject('../../lib/find-dupes.js', { - '../../lib/dedupe.js': function (args, cb) { - t.ok(args.dryRun, 'dryRun is true') - cb() +const FindDupes = require('../../lib/find-dupes.js') + +t.test('should run dedupe in dryRun mode', (t) => { + t.plan(3) + const findDupesTest = new FindDupes({ + config: { + set: (k, v) => { + t.match(k, 'dry-run') + t.match(v, true) + }, + }, + commands: { + dedupe: (args, cb) => { + t.match(args, []) + cb() + }, }, }) - findDupes(null, () => { - t.ok(true, 'callback is called') + findDupesTest.exec({}, () => { t.end() }) }) diff --git a/deps/npm/test/lib/fund.js b/deps/npm/test/lib/fund.js index 73f639b6ce..831d76f151 100644 --- a/deps/npm/test/lib/fund.js +++ b/deps/npm/test/lib/fund.js @@ -188,11 +188,10 @@ const _flatOptions = { unicode: false, which: undefined, } -const openUrl = (url, msg, cb) => { - if (url === 'http://npmjs.org') { - cb(new Error('ERROR')) - return - } +const openUrl = async (npm, url, msg) => { + if (url === 'http://npmjs.org') + throw new Error('ERROR') + if (_flatOptions.json) { printUrl = JSON.stringify({ title: msg, @@ -200,16 +199,8 @@ const openUrl = (url, msg, cb) => { }) } else printUrl = `${msg}:\n ${url}` - - cb() } -const fund = requireInject('../../lib/fund.js', { - '../../lib/npm.js': { - flatOptions: _flatOptions, - get prefix () { - return _flatOptions.prefix - }, - }, +const Fund = requireInject('../../lib/fund.js', { '../../lib/utils/open-url.js': openUrl, '../../lib/utils/output.js': msg => { result += msg + '\n' @@ -222,6 +213,12 @@ const fund = requireInject('../../lib/fund.js', { : Promise.reject(new Error('ERROR')), }, }) +const fund = new Fund({ + flatOptions: _flatOptions, + get prefix () { + return _flatOptions.prefix + }, +}) test('fund with no package containing funding', t => { _flatOptions.prefix = t.testdir({ @@ -231,7 +228,7 @@ test('fund with no package containing funding', t => { }), }) - fund([], (err) => { + fund.exec([], (err) => { t.ifError(err, 'should not error out') t.matchSnapshot(result, 'should print empty funding info') result = '' @@ -242,7 +239,7 @@ test('fund with no package containing funding', t => { test('fund in which same maintainer owns all its deps', t => { _flatOptions.prefix = t.testdir(maintainerOwnsAllDeps) - fund([], (err) => { + fund.exec([], (err) => { t.ifError(err, 'should not error out') t.matchSnapshot(result, 'should print stack packages together') result = '' @@ -254,7 +251,7 @@ test('fund in which same maintainer owns all its deps, using --json option', t = _flatOptions.json = true _flatOptions.prefix = t.testdir(maintainerOwnsAllDeps) - fund([], (err) => { + fund.exec([], (err) => { t.ifError(err, 'should not error out') t.deepEqual( JSON.parse(result), @@ -292,7 +289,7 @@ test('fund in which same maintainer owns all its deps, using --json option', t = test('fund containing multi-level nested deps with no funding', t => { _flatOptions.prefix = t.testdir(nestedNoFundingPackages) - fund([], (err) => { + fund.exec([], (err) => { t.ifError(err, 'should not error out') t.matchSnapshot( result, @@ -308,7 +305,7 @@ test('fund containing multi-level nested deps with no funding, using --json opti _flatOptions.prefix = t.testdir(nestedNoFundingPackages) _flatOptions.json = true - fund([], (err) => { + fund.exec([], (err) => { t.ifError(err, 'should not error out') t.deepEqual( JSON.parse(result), @@ -340,7 +337,7 @@ test('fund containing multi-level nested deps with no funding, using --json opti _flatOptions.prefix = t.testdir(nestedMultipleFundingPackages) _flatOptions.json = true - fund([], (err) => { + fund.exec([], (err) => { t.ifError(err, 'should not error out') t.deepEqual( JSON.parse(result), @@ -397,7 +394,7 @@ test('fund does not support global', t => { _flatOptions.prefix = t.testdir({}) _flatOptions.global = true - fund([], (err) => { + fund.exec([], (err) => { t.match(err.code, 'EFUNDGLOBAL', 'should throw EFUNDGLOBAL error') result = '' @@ -409,7 +406,7 @@ test('fund does not support global', t => { test('fund using package argument', t => { _flatOptions.prefix = t.testdir(maintainerOwnsAllDeps) - fund(['.'], (err) => { + fund.exec(['.'], (err) => { t.ifError(err, 'should not error out') t.matchSnapshot(printUrl, 'should open funding url') @@ -423,7 +420,7 @@ test('fund does not support global, using --json option', t => { _flatOptions.global = true _flatOptions.json = true - fund([], (err) => { + fund.exec([], (err) => { t.equal(err.code, 'EFUNDGLOBAL', 'should use EFUNDGLOBAL error code') t.equal( err.message, @@ -446,7 +443,7 @@ test('fund using string shorthand', t => { }), }) - fund(['.'], (err) => { + fund.exec(['.'], (err) => { t.ifError(err, 'should not error out') t.matchSnapshot(printUrl, 'should open string-only url') @@ -458,7 +455,7 @@ test('fund using string shorthand', t => { test('fund using nested packages with multiple sources', t => { _flatOptions.prefix = t.testdir(nestedMultipleFundingPackages) - fund(['.'], (err) => { + fund.exec(['.'], (err) => { t.ifError(err, 'should not error out') t.matchSnapshot(result, 'should prompt with all available URLs') @@ -486,7 +483,7 @@ test('fund using symlink ref', t => { }) // using symlinked ref - fund(['./node_modules/a'], (err) => { + fund.exec(['./node_modules/a'], (err) => { t.ifError(err, 'should not error out') t.match( printUrl, @@ -497,7 +494,7 @@ test('fund using symlink ref', t => { printUrl = '' // using target ref - fund(['./a'], (err) => { + fund.exec(['./a'], (err) => { t.ifError(err, 'should not error out') t.match( @@ -547,7 +544,7 @@ test('fund using data from actual tree', t => { }) // using symlinked ref - fund(['a'], (err) => { + fund.exec(['a'], (err) => { t.ifError(err, 'should not error out') t.match( printUrl, @@ -564,7 +561,7 @@ test('fund using nested packages with multiple sources, with a source number', t _flatOptions.prefix = t.testdir(nestedMultipleFundingPackages) _flatOptions.which = '1' - fund(['.'], (err) => { + fund.exec(['.'], (err) => { t.ifError(err, 'should not error out') t.matchSnapshot(printUrl, 'should open the numbered URL') @@ -578,7 +575,7 @@ test('fund using pkg name while having conflicting versions', t => { _flatOptions.prefix = t.testdir(conflictingFundingPackages) _flatOptions.which = '1' - fund(['foo'], (err) => { + fund.exec(['foo'], (err) => { t.ifError(err, 'should not error out') t.matchSnapshot(printUrl, 'should open greatest version') @@ -591,7 +588,7 @@ test('fund using package argument with no browser, using --json option', t => { _flatOptions.prefix = t.testdir(maintainerOwnsAllDeps) _flatOptions.json = true - fund(['.'], (err) => { + fund.exec(['.'], (err) => { t.ifError(err, 'should not error out') t.deepEqual( JSON.parse(printUrl), @@ -611,7 +608,7 @@ test('fund using package argument with no browser, using --json option', t => { test('fund using package info fetch from registry', t => { _flatOptions.prefix = t.testdir({}) - fund(['ntl'], (err) => { + fund.exec(['ntl'], (err) => { t.ifError(err, 'should not error out') t.match( printUrl, @@ -627,7 +624,7 @@ test('fund using package info fetch from registry', t => { test('fund tries to use package info fetch from registry but registry has nothing', t => { _flatOptions.prefix = t.testdir({}) - fund(['foo'], (err) => { + fund.exec(['foo'], (err) => { t.equal(err.code, 'ENOFUND', 'should have ENOFUND error code') t.equal( err.message, @@ -643,7 +640,7 @@ test('fund tries to use package info fetch from registry but registry has nothin test('fund but target module has no funding info', t => { _flatOptions.prefix = t.testdir(nestedNoFundingPackages) - fund(['foo'], (err) => { + fund.exec(['foo'], (err) => { t.equal(err.code, 'ENOFUND', 'should have ENOFUND error code') t.equal( err.message, @@ -660,7 +657,7 @@ test('fund using bad which value', t => { _flatOptions.prefix = t.testdir(nestedMultipleFundingPackages) _flatOptions.which = 3 - fund(['bar'], (err) => { + fund.exec(['bar'], (err) => { t.equal(err.code, 'EFUNDNUMBER', 'should have EFUNDNUMBER error code') t.equal( err.message, @@ -682,7 +679,7 @@ test('fund pkg missing version number', t => { }), }) - fund([], (err) => { + fund.exec([], (err) => { t.ifError(err, 'should not error out') t.matchSnapshot(result, 'should print name only') result = '' @@ -699,7 +696,7 @@ test('fund a package throws on openUrl', t => { }), }) - fund(['.'], (err) => { + fund.exec(['.'], (err) => { t.equal(err.message, 'ERROR', 'should throw unknown error') result = '' t.end() @@ -723,7 +720,7 @@ test('fund a package with type and multiple sources', t => { }), }) - fund(['.'], (err) => { + fund.exec(['.'], (err) => { t.ifError(err, 'should not error out') t.matchSnapshot(result, 'should print prompt select message') @@ -787,7 +784,7 @@ test('fund colors', t => { }) _flatOptions.color = true - fund([], (err) => { + fund.exec([], (err) => { t.ifError(err, 'should not error out') t.matchSnapshot(result, 'should print output with color info') @@ -837,7 +834,7 @@ test('sub dep with fund info and a parent with no funding info', t => { }, }) - fund([], (err) => { + fund.exec([], (err) => { t.ifError(err, 'should not error out') t.matchSnapshot(result, 'should nest sub dep as child of root') diff --git a/deps/npm/test/lib/get.js b/deps/npm/test/lib/get.js index 5260c00bae..a11597d268 100644 --- a/deps/npm/test/lib/get.js +++ b/deps/npm/test/lib/get.js @@ -2,17 +2,16 @@ const { test } = require('tap') const requireInject = require('require-inject') test('should retrieve values from npm.commands.config', (t) => { - const get = requireInject('../../lib/get.js', { - '../../lib/npm.js': { - commands: { - config: ([action, arg]) => { - t.equal(action, 'get', 'should use config get action') - t.equal(arg, 'foo', 'should use expected key') - t.end() - }, + const Get = requireInject('../../lib/get.js') + const get = new Get({ + commands: { + config: ([action, arg]) => { + t.equal(action, 'get', 'should use config get action') + t.equal(arg, 'foo', 'should use expected key') + t.end() }, }, }) - get(['foo']) + get.exec(['foo']) }) diff --git a/deps/npm/test/lib/help-search.js b/deps/npm/test/lib/help-search.js index f74e2f1efe..8b1ecd46eb 100644 --- a/deps/npm/test/lib/help-search.js +++ b/deps/npm/test/lib/help-search.js @@ -24,7 +24,7 @@ const npm = { } let npmUsageArg = null -const npmUsage = (arg) => { +const npmUsage = (npm, arg) => { npmUsageArg = arg } @@ -43,12 +43,12 @@ const globDir = { const glob = (p, cb) => cb(null, Object.keys(globDir).map((file) => join(globRoot, file))) -const helpSearch = requireInject('../../lib/help-search.js', { - '../../lib/npm.js': npm, +const HelpSearch = requireInject('../../lib/help-search.js', { '../../lib/utils/npm-usage.js': npmUsage, '../../lib/utils/output.js': output, glob, }) +const helpSearch = new HelpSearch(npm) test('npm help-search', t => { globRoot = t.testdir(globDir) @@ -57,7 +57,7 @@ test('npm help-search', t => { globRoot = null }) - return helpSearch(['exec'], (err) => { + return helpSearch.exec(['exec'], (err) => { if (err) throw err @@ -74,7 +74,7 @@ test('npm help-search multiple terms', t => { globRoot = null }) - return helpSearch(['run', 'script'], (err) => { + return helpSearch.exec(['run', 'script'], (err) => { if (err) throw err @@ -92,7 +92,7 @@ test('npm help-search single result prints full section', t => { globRoot = null }) - return helpSearch(['does not exist in'], (err) => { + return helpSearch.exec(['does not exist in'], (err) => { if (err) throw err @@ -111,7 +111,7 @@ test('npm help-search single result propagates error', t => { globRoot = null }) - return helpSearch(['does not exist in'], (err) => { + return helpSearch.exec(['does not exist in'], (err) => { t.strictSame(npmHelpArgs, ['npm-install'], 'identified the correct man page and called help with it') t.match(err, /help broke/, 'propagated the error from help') t.end() @@ -127,7 +127,7 @@ test('npm help-search long output', t => { globRoot = null }) - return helpSearch(['exec'], (err) => { + return helpSearch.exec(['exec'], (err) => { if (err) throw err @@ -147,7 +147,7 @@ test('npm help-search long output with color', t => { globRoot = null }) - return helpSearch(['help-search'], (err) => { + return helpSearch.exec(['help-search'], (err) => { if (err) throw err @@ -158,7 +158,7 @@ test('npm help-search long output with color', t => { }) test('npm help-search no args', t => { - return helpSearch([], (err) => { + return helpSearch.exec([], (err) => { t.match(err, /npm help-search/, 'throws usage') t.end() }) @@ -172,7 +172,7 @@ test('npm help-search no matches', t => { globRoot = null }) - return helpSearch(['asdfasdf'], (err) => { + return helpSearch.exec(['asdfasdf'], (err) => { if (err) throw err diff --git a/deps/npm/test/lib/help.js b/deps/npm/test/lib/help.js index fc4a32e07b..addbe4dcc1 100644 --- a/deps/npm/test/lib/help.js +++ b/deps/npm/test/lib/help.js @@ -3,7 +3,7 @@ const requireInject = require('require-inject') const { EventEmitter } = require('events') let npmUsageArg = null -const npmUsage = (arg) => { +const npmUsage = (npm, arg) => { npmUsageArg = arg } @@ -67,13 +67,11 @@ const spawn = (bin, args) => { } let openUrlArg = null -const openUrl = (url, msg, cb) => { +const openUrl = async (npm, url, msg) => { openUrlArg = url - return cb() } -const help = requireInject('../../lib/help.js', { - '../../lib/npm.js': npm, +const Help = requireInject('../../lib/help.js', { '../../lib/utils/npm-usage.js': npmUsage, '../../lib/utils/open-url.js': openUrl, '../../lib/utils/output.js': output, @@ -82,13 +80,14 @@ const help = requireInject('../../lib/help.js', { }, glob, }) +const help = new Help(npm) test('npm help', t => { t.teardown(() => { npmUsageArg = null }) - return help([], (err) => { + return help.exec([], (err) => { if (err) throw err @@ -117,7 +116,7 @@ test('npm help -h', t => { OUTPUT.length = 0 }) - return help(['help'], (err) => { + return help.exec(['help'], (err) => { if (err) throw err @@ -131,7 +130,7 @@ test('npm help multiple args calls search', t => { helpSearchArgs = null }) - return help(['run', 'script'], (err) => { + return help.exec(['run', 'script'], (err) => { if (err) throw err @@ -147,7 +146,7 @@ test('npm help no matches calls search', t => { globResult = globDefaults }) - return help(['asdfasdf'], (err) => { + return help.exec(['asdfasdf'], (err) => { if (err) throw err @@ -164,7 +163,7 @@ test('npm help glob errors propagate', t => { spawnArgs = null }) - return help(['whoami'], (err) => { + return help.exec(['whoami'], (err) => { t.match(err, /glob failed/, 'glob error propagates') t.end() }) @@ -178,7 +177,7 @@ test('npm help whoami', t => { spawnArgs = null }) - return help(['whoami'], (err) => { + return help.exec(['whoami'], (err) => { if (err) throw err @@ -202,7 +201,7 @@ test('npm help 1 install', t => { spawnArgs = null }) - return help(['1', 'install'], (err) => { + return help.exec(['1', 'install'], (err) => { if (err) throw err @@ -225,7 +224,7 @@ test('npm help 5 install', t => { spawnArgs = null }) - return help(['5', 'install'], (err) => { + return help.exec(['5', 'install'], (err) => { if (err) throw err @@ -247,7 +246,7 @@ test('npm help 7 config', t => { spawnArgs = null }) - return help(['7', 'config'], (err) => { + return help.exec(['7', 'config'], (err) => { if (err) throw err @@ -270,7 +269,7 @@ test('npm help with browser viewer and invalid section throws', t => { spawnArgs = null }) - return help(['9', 'config'], (err) => { + return help.exec(['9', 'config'], (err) => { t.match(err, /invalid man section: 9/, 'throws appropriate error') t.end() }) @@ -284,7 +283,7 @@ test('npm help global redirects to folders', t => { spawnArgs = null }) - return help(['global'], (err) => { + return help.exec(['global'], (err) => { if (err) throw err @@ -302,7 +301,7 @@ test('npm help package.json redirects to package-json', t => { spawnArgs = null }) - return help(['package.json'], (err) => { + return help.exec(['package.json'], (err) => { if (err) throw err @@ -325,7 +324,7 @@ test('npm help ?(un)star', t => { spawnArgs = null }) - return help(['?(un)star'], (err) => { + return help.exec(['?(un)star'], (err) => { if (err) throw err @@ -350,7 +349,7 @@ test('npm help - woman viewer propagates errors', t => { spawnArgs = null }) - return help(['?(un)star'], (err) => { + return help.exec(['?(un)star'], (err) => { t.match(err, /help process exited with code: 1/, 'received the correct error') t.equal(spawnBin, 'emacsclient', 'maps woman to emacs correctly') t.strictSame(spawnArgs, ['-e', `(woman-find-file '/root/man/man1/npm-unstar.1')`], 'passes the correct arguments') @@ -370,7 +369,7 @@ test('npm help un*', t => { spawnArgs = null }) - return help(['un*'], (err) => { + return help.exec(['un*'], (err) => { if (err) throw err @@ -394,7 +393,7 @@ test('npm help - man viewer propagates errors', t => { spawnArgs = null }) - return help(['un*'], (err) => { + return help.exec(['un*'], (err) => { t.match(err, /help process exited with code: 1/, 'received correct error') t.equal(spawnBin, 'man', 'calls man by default') t.strictSame(spawnArgs, ['1', 'npm-unstar'], 'passes the correct arguments') diff --git a/deps/npm/test/lib/hook.js b/deps/npm/test/lib/hook.js index 3599042021..923f86e81d 100644 --- a/deps/npm/test/lib/hook.js +++ b/deps/npm/test/lib/hook.js @@ -52,17 +52,17 @@ const libnpmhook = { } const output = [] -const hook = requireInject('../../lib/hook.js', { - '../../lib/npm.js': npm, +const Hook = requireInject('../../lib/hook.js', { '../../lib/utils/otplease.js': async (opts, fn) => fn(opts), '../../lib/utils/output.js': (msg) => { output.push(msg) }, libnpmhook, }) +const hook = new Hook(npm) test('npm hook no args', t => { - return hook([], (err) => { + return hook.exec([], (err) => { t.match(err, /npm hook add/, 'throws usage with no arguments') t.end() }) @@ -74,7 +74,7 @@ test('npm hook add', t => { output.length = 0 }) - return hook(['add', 'semver', 'https://google.com', 'some-secret'], (err) => { + return hook.exec(['add', 'semver', 'https://google.com', 'some-secret'], (err) => { if (err) throw err @@ -97,7 +97,7 @@ test('npm hook add - unicode output', t => { output.length = 0 }) - return hook(['add', 'semver', 'https://google.com', 'some-secret'], (err) => { + return hook.exec(['add', 'semver', 'https://google.com', 'some-secret'], (err) => { if (err) throw err @@ -120,7 +120,7 @@ test('npm hook add - json output', t => { output.length = 0 }) - return hook(['add', '@npmcli', 'https://google.com', 'some-secret'], (err) => { + return hook.exec(['add', '@npmcli', 'https://google.com', 'some-secret'], (err) => { if (err) throw err @@ -148,7 +148,7 @@ test('npm hook add - parseable output', t => { output.length = 0 }) - return hook(['add', '@npmcli', 'https://google.com', 'some-secret'], (err) => { + return hook.exec(['add', '@npmcli', 'https://google.com', 'some-secret'], (err) => { if (err) throw err @@ -176,7 +176,7 @@ test('npm hook add - silent output', t => { output.length = 0 }) - return hook(['add', '@npmcli', 'https://google.com', 'some-secret'], (err) => { + return hook.exec(['add', '@npmcli', 'https://google.com', 'some-secret'], (err) => { if (err) throw err @@ -197,7 +197,7 @@ test('npm hook ls', t => { output.length = 0 }) - return hook(['ls'], (err) => { + return hook.exec(['ls'], (err) => { if (err) throw err @@ -222,7 +222,7 @@ test('npm hook ls, no results', t => { output.length = 0 }) - return hook(['ls'], (err) => { + return hook.exec(['ls'], (err) => { if (err) throw err @@ -249,7 +249,7 @@ test('npm hook ls, single result', t => { output.length = 0 }) - return hook(['ls'], (err) => { + return hook.exec(['ls'], (err) => { if (err) throw err @@ -272,7 +272,7 @@ test('npm hook ls - json output', t => { output.length = 0 }) - return hook(['ls'], (err) => { + return hook.exec(['ls'], (err) => { if (err) throw err @@ -309,7 +309,7 @@ test('npm hook ls - parseable output', t => { output.length = 0 }) - return hook(['ls'], (err) => { + return hook.exec(['ls'], (err) => { if (err) throw err @@ -335,7 +335,7 @@ test('npm hook ls - silent output', t => { output.length = 0 }) - return hook(['ls'], (err) => { + return hook.exec(['ls'], (err) => { if (err) throw err @@ -354,7 +354,7 @@ test('npm hook rm', t => { output.length = 0 }) - return hook(['rm', '1'], (err) => { + return hook.exec(['rm', '1'], (err) => { if (err) throw err @@ -377,7 +377,7 @@ test('npm hook rm - unicode output', t => { output.length = 0 }) - return hook(['rm', '1'], (err) => { + return hook.exec(['rm', '1'], (err) => { if (err) throw err @@ -400,7 +400,7 @@ test('npm hook rm - silent output', t => { output.length = 0 }) - return hook(['rm', '1'], (err) => { + return hook.exec(['rm', '1'], (err) => { if (err) throw err @@ -421,7 +421,7 @@ test('npm hook rm - json output', t => { output.length = 0 }) - return hook(['rm', '1'], (err) => { + return hook.exec(['rm', '1'], (err) => { if (err) throw err @@ -447,7 +447,7 @@ test('npm hook rm - parseable output', t => { output.length = 0 }) - return hook(['rm', '1'], (err) => { + return hook.exec(['rm', '1'], (err) => { if (err) throw err @@ -469,7 +469,7 @@ test('npm hook update', t => { output.length = 0 }) - return hook(['update', '1', 'https://google.com', 'some-secret'], (err) => { + return hook.exec(['update', '1', 'https://google.com', 'some-secret'], (err) => { if (err) throw err @@ -494,7 +494,7 @@ test('npm hook update - unicode', t => { output.length = 0 }) - return hook(['update', '1', 'https://google.com', 'some-secret'], (err) => { + return hook.exec(['update', '1', 'https://google.com', 'some-secret'], (err) => { if (err) throw err @@ -519,7 +519,7 @@ test('npm hook update - json output', t => { output.length = 0 }) - return hook(['update', '1', 'https://google.com', 'some-secret'], (err) => { + return hook.exec(['update', '1', 'https://google.com', 'some-secret'], (err) => { if (err) throw err @@ -547,7 +547,7 @@ test('npm hook update - parseable output', t => { output.length = 0 }) - return hook(['update', '1', 'https://google.com', 'some-secret'], (err) => { + return hook.exec(['update', '1', 'https://google.com', 'some-secret'], (err) => { if (err) throw err @@ -573,7 +573,7 @@ test('npm hook update - silent output', t => { output.length = 0 }) - return hook(['update', '1', 'https://google.com', 'some-secret'], (err) => { + return hook.exec(['update', '1', 'https://google.com', 'some-secret'], (err) => { if (err) throw err diff --git a/deps/npm/test/lib/init.js b/deps/npm/test/lib/init.js index e73cc4b309..db5411ba76 100644 --- a/deps/npm/test/lib/init.js +++ b/deps/npm/test/lib/init.js @@ -17,13 +17,13 @@ const npm = { } const mocks = { 'init-package-json': (dir, initFile, config, cb) => cb(null, 'data'), - '../../lib/npm.js': npm, '../../lib/utils/usage.js': () => 'usage instructions', '../../lib/utils/output.js': (...msg) => { result += msg.join('\n') }, } -const init = requireInject('../../lib/init.js', mocks) +const Init = requireInject('../../lib/init.js', mocks) +const init = new Init(npm) t.afterEach(cb => { result = '' @@ -40,7 +40,7 @@ t.test('classic npm init no args', t => { return '~/.npm-init.js' }, } - init([], err => { + init.exec([], err => { t.ifError(err, 'npm init no args') t.matchSnapshot(result, 'should print helper info') t.end() @@ -65,7 +65,7 @@ t.test('classic npm init -y', t => { t.equal(title, 'init', 'should print title') t.equal(msg, 'written successfully', 'should print done info') } - init([], err => { + init.exec([], err => { t.ifError(err, 'npm init -y') t.equal(result, '') }) @@ -87,7 +87,7 @@ t.test('npm init <arg>', t => { ) cb() } - init(['react-app'], err => { + init.exec(['react-app'], err => { t.ifError(err, 'npm init react-app') }) }) @@ -102,7 +102,7 @@ t.test('npm init @scope/name', t => { ) cb() } - init(['@npmcli/something'], err => { + init.exec(['@npmcli/something'], err => { t.ifError(err, 'npm init init @scope/name') }) }) @@ -117,7 +117,7 @@ t.test('npm init git spec', t => { ) cb() } - init(['npm/something'], err => { + init.exec(['npm/something'], err => { t.ifError(err, 'npm init init @scope/name') }) }) @@ -132,13 +132,13 @@ t.test('npm init @scope', t => { ) cb() } - init(['@npmcli'], err => { + init.exec(['@npmcli'], err => { t.ifError(err, 'npm init init @scope/create') }) }) t.test('npm init tgz', t => { - init(['something.tgz'], err => { + init.exec(['something.tgz'], err => { t.match( err, /Error: Unrecognized initializer: something.tgz/, @@ -158,7 +158,7 @@ t.test('npm init <arg>@next', t => { ) cb() } - init(['something@next'], err => { + init.exec(['something@next'], err => { t.ifError(err, 'npm init init something@next') }) }) @@ -167,7 +167,7 @@ t.test('npm init exec error', t => { npm.commands.exec = (arr, cb) => { cb(new Error('ERROR')) } - init(['something@next'], err => { + init.exec(['something@next'], err => { t.match( err, /ERROR/, @@ -199,37 +199,39 @@ t.test('should not rewrite flatOptions', t => { ) cb() } - init(['react-app', 'my-app'], err => { + init.exec(['react-app', 'my-app'], err => { t.ifError(err, 'npm init react-app') }) }) t.test('npm init cancel', t => { t.plan(3) - const init = requireInject('../../lib/init.js', { + const Init = requireInject('../../lib/init.js', { ...mocks, 'init-package-json': (dir, initFile, config, cb) => cb( new Error('canceled') ), }) + const init = new Init(npm) npm.log = { ...npm.log } npm.log.warn = (title, msg) => { t.equal(title, 'init', 'should have init title') t.equal(msg, 'canceled', 'should log canceled') } - init([], err => { + init.exec([], err => { t.ifError(err, 'npm init cancel') }) }) t.test('npm init error', t => { - const init = requireInject('../../lib/init.js', { + const Init = requireInject('../../lib/init.js', { ...mocks, 'init-package-json': (dir, initFile, config, cb) => cb( new Error('Unknown Error') ), }) - init([], err => { + const init = new Init(npm) + init.exec([], err => { t.match(err, /Unknown Error/, 'should throw error') t.end() }) diff --git a/deps/npm/test/lib/install-ci-test.js b/deps/npm/test/lib/install-ci-test.js new file mode 100644 index 0000000000..5f30efcabf --- /dev/null +++ b/deps/npm/test/lib/install-ci-test.js @@ -0,0 +1,57 @@ +const t = require('tap') + +const InstallCITest = require('../../lib/install-ci-test.js') + +let ciArgs = null +let ciCalled = false +let testArgs = null +let testCalled = false +let ciError = null + +const installCITest = new InstallCITest({ + commands: { + ci: (args, cb) => { + ciArgs = args + ciCalled = true + cb(ciError) + }, + test: (args, cb) => { + testArgs = args + testCalled = true + cb() + }, + }, +}) + +t.test('the install-ci-test command', t => { + t.afterEach(cb => { + ciArgs = null + ciCalled = false + testArgs = null + testCalled = false + ciError = null + cb() + }) + + t.test('ci and test', t => { + installCITest.exec(['extra'], () => { + t.equal(ciCalled, true) + t.equal(testCalled, true) + t.match(ciArgs, ['extra']) + t.match(testArgs, []) + t.end() + }) + }) + + t.test('ci fails', t => { + ciError = new Error('test fail') + installCITest.exec(['extra'], (err) => { + t.equal(ciCalled, true) + t.equal(testCalled, false) + t.match(ciArgs, ['extra']) + t.match(err, { message: 'test fail' }) + t.end() + }) + }) + t.end() +}) diff --git a/deps/npm/test/lib/install-test.js b/deps/npm/test/lib/install-test.js new file mode 100644 index 0000000000..0c52bd5e3c --- /dev/null +++ b/deps/npm/test/lib/install-test.js @@ -0,0 +1,57 @@ +const t = require('tap') + +const InstallTest = require('../../lib/install-test.js') + +let installArgs = null +let installCalled = false +let testArgs = null +let testCalled = false +let installError = null + +const installTest = new InstallTest({ + commands: { + install: (args, cb) => { + installArgs = args + installCalled = true + cb(installError) + }, + test: (args, cb) => { + testArgs = args + testCalled = true + cb() + }, + }, +}) + +t.test('the install-test command', t => { + t.afterEach(cb => { + installArgs = null + installCalled = false + testArgs = null + testCalled = false + installError = null + cb() + }) + + t.test('install and test', t => { + installTest.exec(['extra'], () => { + t.equal(installCalled, true) + t.equal(testCalled, true) + t.match(installArgs, ['extra']) + t.match(testArgs, []) + t.end() + }) + }) + + t.test('install fails', t => { + installError = new Error('test fail') + installTest.exec(['extra'], (err) => { + t.equal(installCalled, true) + t.equal(testCalled, false) + t.match(installArgs, ['extra']) + t.match(err, { message: 'test fail' }) + t.end() + }) + }) + t.end() +}) diff --git a/deps/npm/test/lib/install.js b/deps/npm/test/lib/install.js index 859a4bdaaa..8b7a968511 100644 --- a/deps/npm/test/lib/install.js +++ b/deps/npm/test/lib/install.js @@ -1,6 +1,6 @@ const { test } = require('tap') -const install = require('../../lib/install.js') +const Install = require('../../lib/install.js') const requireInject = require('require-inject') test('should install using Arborist', (t) => { @@ -9,17 +9,7 @@ test('should install using Arborist', (t) => { let REIFY_CALLED = false let ARB_OBJ = null - const install = requireInject('../../lib/install.js', { - '../../lib/npm.js': { - globalDir: 'path/to/node_modules/', - prefix: 'foo', - flatOptions: { - global: false, - }, - config: { - get: () => true, - }, - }, + const Install = requireInject('../../lib/install.js', { '@npmcli/run-script': ({ event }) => { SCRIPTS.push(event) }, @@ -33,14 +23,24 @@ test('should install using Arborist', (t) => { REIFY_CALLED = true } }, - '../../lib/utils/reify-finish.js': arb => { + '../../lib/utils/reify-finish.js': (npm, arb) => { if (arb !== ARB_OBJ) throw new Error('got wrong object passed to reify-finish') }, }) + const install = new Install({ + globalDir: 'path/to/node_modules/', + prefix: 'foo', + flatOptions: { + global: false, + }, + config: { + get: () => true, + }, + }) t.test('with args', t => { - install(['fizzbuzz'], er => { + install.exec(['fizzbuzz'], er => { if (er) throw er t.match(ARB_ARGS, { global: false, path: 'foo' }) @@ -51,7 +51,7 @@ test('should install using Arborist', (t) => { }) t.test('just a local npm install', t => { - install([], er => { + install.exec([], er => { if (er) throw er t.match(ARB_ARGS, { global: false, path: 'foo' }) @@ -75,19 +75,8 @@ test('should install using Arborist', (t) => { test('should ignore scripts with --ignore-scripts', (t) => { const SCRIPTS = [] let REIFY_CALLED = false - const install = requireInject('../../lib/install.js', { + const Install = requireInject('../../lib/install.js', { '../../lib/utils/reify-finish.js': async () => {}, - '../../lib/npm.js': { - globalDir: 'path/to/node_modules/', - prefix: 'foo', - flatOptions: { - global: false, - ignoreScripts: true, - }, - config: { - get: () => false, - }, - }, '@npmcli/run-script': ({ event }) => { SCRIPTS.push(event) }, @@ -97,7 +86,18 @@ test('should ignore scripts with --ignore-scripts', (t) => { } }, }) - install([], er => { + const install = new Install({ + globalDir: 'path/to/node_modules/', + prefix: 'foo', + flatOptions: { + global: false, + ignoreScripts: true, + }, + config: { + get: () => false, + }, + }) + install.exec([], er => { if (er) throw er t.equal(REIFY_CALLED, true, 'called reify') @@ -107,23 +107,23 @@ test('should ignore scripts with --ignore-scripts', (t) => { }) test('should install globally using Arborist', (t) => { - const install = requireInject('../../lib/install.js', { + const Install = requireInject('../../lib/install.js', { '../../lib/utils/reify-finish.js': async () => {}, - '../../lib/npm.js': { - globalDir: 'path/to/node_modules/', - prefix: 'foo', - flatOptions: { - global: true, - }, - config: { - get: () => false, - }, - }, '@npmcli/arborist': function () { this.reify = () => {} }, }) - install([], er => { + const install = new Install({ + globalDir: 'path/to/node_modules/', + prefix: 'foo', + flatOptions: { + global: true, + }, + config: { + get: () => false, + }, + }) + install.exec([], er => { if (er) throw er t.end() @@ -131,7 +131,7 @@ test('should install globally using Arborist', (t) => { }) test('completion to folder', async t => { - const install = requireInject('../../lib/install.js', { + const Install = requireInject('../../lib/install.js', { '../../lib/utils/reify-finish.js': async () => {}, util: { promisify: (fn) => fn, @@ -145,6 +145,7 @@ test('completion to folder', async t => { }, }, }) + const install = new Install({}) const res = await install.completion({ partialWord: '/ar' }) const expect = process.platform === 'win32' ? '\\arborist' : '/arborist' t.strictSame(res, [expect], 'package dir match') @@ -152,7 +153,7 @@ test('completion to folder', async t => { }) test('completion to folder - invalid dir', async t => { - const install = requireInject('../../lib/install.js', { + const Install = requireInject('../../lib/install.js', { '../../lib/utils/reify-finish.js': async () => {}, util: { promisify: (fn) => fn, @@ -163,13 +164,14 @@ test('completion to folder - invalid dir', async t => { }, }, }) + const install = new Install({}) const res = await install.completion({ partialWord: 'path/to/folder' }) t.strictSame(res, [], 'invalid dir: no matching') t.end() }) test('completion to folder - no matches', async t => { - const install = requireInject('../../lib/install.js', { + const Install = requireInject('../../lib/install.js', { '../../lib/utils/reify-finish.js': async () => {}, util: { promisify: (fn) => fn, @@ -180,13 +182,14 @@ test('completion to folder - no matches', async t => { }, }, }) + const install = new Install({}) const res = await install.completion({ partialWord: '/pa' }) t.strictSame(res, [], 'no name match') t.end() }) test('completion to folder - match is not a package', async t => { - const install = requireInject('../../lib/install.js', { + const Install = requireInject('../../lib/install.js', { '../../lib/utils/reify-finish.js': async () => {}, util: { promisify: (fn) => fn, @@ -200,18 +203,21 @@ test('completion to folder - match is not a package', async t => { }, }, }) + const install = new Install({}) const res = await install.completion({ partialWord: '/ar' }) t.strictSame(res, [], 'no name match') t.end() }) test('completion to url', async t => { + const install = new Install({}) const res = await install.completion({ partialWord: 'http://path/to/url' }) t.strictSame(res, []) t.end() }) test('completion', async t => { + const install = new Install({}) const res = await install.completion({ partialWord: 'toto' }) t.notOk(res) t.end() diff --git a/deps/npm/test/lib/link.js b/deps/npm/test/lib/link.js index b1048427d7..be7af3f524 100644 --- a/deps/npm/test/lib/link.js +++ b/deps/npm/test/lib/link.js @@ -40,11 +40,11 @@ const printLinks = async (opts) => { } const mocks = { - '../../lib/npm.js': npm, '../../lib/utils/reify-output.js': () => reifyOutput(), } -const link = requireInject('../../lib/link.js', mocks) +const Link = requireInject('../../lib/link.js', mocks) +const link = new Link(npm) t.test('link to globalDir when in current working dir of pkg and no args', (t) => { t.plan(2) @@ -83,7 +83,7 @@ t.test('link to globalDir when in current working dir of pkg and no args', (t) = t.matchSnapshot(links, 'should create a global link to current pkg') } - link([], (err) => { + link.exec([], (err) => { t.ifError(err, 'should not error out') }) }) @@ -185,7 +185,7 @@ t.test('link global linked pkg to local nm when using args', (t) => { // - @myscope/bar: prev installed scoped package available in globalDir // - a: prev installed package available in globalDir // - file:./link-me-too: pkg that needs to be reified in globalDir first - link([ + link.exec([ 'test-pkg-link', '@myscope/linked', '@myscope/bar', @@ -254,7 +254,7 @@ t.test('link pkg already in global space', (t) => { // - @myscope/bar: prev installed scoped package available in globalDir // - a: prev installed package available in globalDir // - file:./link-me-too: pkg that needs to be reified in globalDir first - link(['@myscope/linked'], (err) => { + link.exec(['@myscope/linked'], (err) => { t.ifError(err, 'should not error out') }) }) @@ -312,7 +312,7 @@ t.test('link pkg already in global space when prefix is a symlink', (t) => { t.matchSnapshot(links, 'should create a local symlink to global pkg') } - link(['@myscope/linked'], (err) => { + link.exec(['@myscope/linked'], (err) => { t.ifError(err, 'should not error out') }) }) @@ -341,21 +341,18 @@ t.test('completion', async t => { t.end() }) -t.test('--global option', async t => { +t.test('--global option', t => { const _config = npm.config npm.config = { get () { return true } } - try { - await link([]) - t.fail('should not get here') - } catch (err) { + link.exec([], (err) => { npm.config = _config t.match( err.message, /link should never be --global/, 'should throw an useful error' ) - } - t.end() + t.end() + }) }) diff --git a/deps/npm/test/lib/ll.js b/deps/npm/test/lib/ll.js index 7d4e2b94f2..45eb4ec95b 100644 --- a/deps/npm/test/lib/ll.js +++ b/deps/npm/test/lib/ll.js @@ -1,31 +1,34 @@ -const t = require('tap') const requireInject = require('require-inject') -const configs = {} -let lsCalled = false -const ll = requireInject('../../lib/ll.js', { - '../../lib/npm.js': { +const t = require('tap') + +t.test('ll', t => { + t.plan(3) + + class LS { + constructor (npm) { + this.npm = npm + } + + exec (args, cb) { + t.deepEqual(args, ['pkg'], 'should forward args') + cb() + } + } + + const LL = requireInject('../../lib/ll.js', { + '../../lib/ls.js': LS, + }) + const ll = new LL({ config: { - set: (k, v) => { - configs[k] = v - }, - }, - commands: { - ls: (args, cb) => { - lsCalled = true - cb() + set: (key, value) => { + t.equal(key, 'long', 'should set long config value') + t.equal(value, true, 'should set a truthy value') }, }, - }, -}) + }) -const ls = require('../../lib/ls.js') -const { usage, completion } = ls -t.equal(ll.usage, usage) -t.equal(ll.completion.toString(), completion.toString()) -t.test('the ll command', t => { - ll([], () => { - t.equal(lsCalled, true) - t.strictSame(configs, { long: true }) - t.end() + ll.exec(['pkg'], err => { + if (err) + throw err }) }) diff --git a/deps/npm/test/lib/load-all-commands.js b/deps/npm/test/lib/load-all-commands.js index 02cb0be650..f6d1ae9e18 100644 --- a/deps/npm/test/lib/load-all-commands.js +++ b/deps/npm/test/lib/load-all-commands.js @@ -1,4 +1,6 @@ -// just for gathering coverage info +// Thanks to nyc not working properly with proxies this +// doesn't affect coverage. but it does ensure that every command +// has a usage, and if it has completion it is a function const npm = require('../../lib/npm.js') const t = require('tap') const { cmdList } = require('../../lib/utils/cmd-list.js') @@ -19,7 +21,7 @@ t.test('load each command', t => { } else t.plan(2) t.isa(impl, 'function', 'implementation is a function') - t.isa(impl.usage, 'string', 'usage is a string') + t.match(impl.usage, cmd, 'usage contains the command') }) } }) diff --git a/deps/npm/test/lib/logout.js b/deps/npm/test/lib/logout.js index 96b1bcc7fe..b00fa641d8 100644 --- a/deps/npm/test/lib/logout.js +++ b/deps/npm/test/lib/logout.js @@ -17,13 +17,13 @@ const npmFetch = (url, opts) => { const mocks = { npmlog, 'npm-registry-fetch': npmFetch, - '../../lib/npm.js': { - flatOptions: _flatOptions, - config, - }, } -const logout = requireInject('../../lib/logout.js', mocks) +const Logout = requireInject('../../lib/logout.js', mocks) +const logout = new Logout({ + flatOptions: _flatOptions, + config, +}) test('token logout', async (t) => { t.plan(6) @@ -52,7 +52,7 @@ test('token logout', async (t) => { } await new Promise((res, rej) => { - logout([], (err) => { + logout.exec([], (err) => { t.ifError(err, 'should not error out') t.deepEqual( @@ -121,7 +121,7 @@ test('token scoped logout', async (t) => { } await new Promise((res, rej) => { - logout([], (err) => { + logout.exec([], (err) => { t.ifError(err, 'should not error out') t.deepEqual( @@ -174,7 +174,7 @@ test('user/pass logout', async (t) => { config.save = () => null await new Promise((res, rej) => { - logout([], (err) => { + logout.exec([], (err) => { t.ifError(err, 'should not error out') delete _flatOptions.username @@ -189,7 +189,7 @@ test('user/pass logout', async (t) => { }) test('missing credentials', (t) => { - logout([], (err) => { + logout.exec([], (err) => { t.match( err.message, /not logged in to https:\/\/registry.npmjs.org\/, so can't log out!/, @@ -228,7 +228,7 @@ test('ignore invalid scoped registry config', async (t) => { config.save = () => null await new Promise((res, rej) => { - logout([], (err) => { + logout.exec([], (err) => { t.ifError(err, 'should not error out') t.deepEqual( diff --git a/deps/npm/test/lib/ls.js b/deps/npm/test/lib/ls.js index b1df9067c3..bd81776d5f 100644 --- a/deps/npm/test/lib/ls.js +++ b/deps/npm/test/lib/ls.js @@ -106,28 +106,28 @@ const _flatOptions = { }, production: false, } -const ls = requireInject('../../lib/ls.js', { - '../../lib/npm.js': { - flatOptions: _flatOptions, - limit: { - fetch: 3, - }, - get prefix () { - return _flatOptions.prefix - }, - get globalDir () { - return globalDir - }, - config: { - get (key) { - return _flatOptions[key] - }, - }, - }, +const LS = requireInject('../../lib/ls.js', { '../../lib/utils/output.js': msg => { result = msg }, }) +const ls = new LS({ + flatOptions: _flatOptions, + limit: { + fetch: 3, + }, + get prefix () { + return _flatOptions.prefix + }, + get globalDir () { + return globalDir + }, + config: { + get (key) { + return _flatOptions[key] + }, + }, +}) const redactCwd = res => res && res.replace(/\\+/g, '/').replace(new RegExp(__dirname.replace(/\\+/g, '/'), 'gi'), '{CWD}') @@ -155,7 +155,7 @@ t.test('ls', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output tree representation of dependencies structure') t.end() @@ -166,7 +166,7 @@ t.test('ls', (t) => { prefix = t.testdir({ ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err.code, 'ELSPROBLEMS', 'should have ELSPROBLEMS error code') t.matchSnapshot( redactCwd(err.message), @@ -188,7 +188,7 @@ t.test('ls', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.equal(err.code, 'ELSPROBLEMS', 'should have error code') t.equal( redactCwd(err.message), @@ -213,7 +213,7 @@ t.test('ls', (t) => { }), ...simpleNmFixture, }) - ls(['lorem'], (err) => { + ls.exec(['lorem'], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output tree contaning only occurrences of filtered by package and colored output') _flatOptions.color = false @@ -235,7 +235,7 @@ t.test('ls', (t) => { }), ...simpleNmFixture, }) - ls(['.'], (err) => { + ls.exec(['.'], (err) => { t.ifError(err, 'should not throw on missing dep above current level') t.matchSnapshot(redactCwd(result), 'should output tree contaning only occurrences of filtered by package and colored output') _flatOptions.all = true @@ -256,7 +256,7 @@ t.test('ls', (t) => { }), ...simpleNmFixture, }) - ls(['bar'], (err) => { + ls.exec(['bar'], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output tree contaning only occurrences of filtered package and its ancestors') t.end() @@ -284,7 +284,7 @@ t.test('ls', (t) => { }, }, }) - ls(['bar@*', 'lorem@1.0.0'], (err) => { + ls.exec(['bar@*', 'lorem@1.0.0'], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output tree contaning only occurrences of multiple filtered packages and their ancestors') t.end() @@ -303,7 +303,7 @@ t.test('ls', (t) => { }), ...simpleNmFixture, }) - ls(['notadep'], (err) => { + ls.exec(['notadep'], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output tree containing no dependencies info') t.equal( @@ -330,7 +330,7 @@ t.test('ls', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output tree containing only top-level dependencies') _flatOptions.all = true @@ -353,7 +353,7 @@ t.test('ls', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output tree containing only top-level dependencies') _flatOptions.all = true @@ -414,7 +414,7 @@ t.test('ls', (t) => { }, }, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output tree containing top-level deps and their deps only') _flatOptions.all = true @@ -435,7 +435,7 @@ t.test('ls', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.equal(err.code, 'ELSPROBLEMS', 'should have error code') t.equal( redactCwd(err.message).replace(/\r\n/g, '\n'), @@ -462,7 +462,7 @@ t.test('ls', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.equal(err.code, 'ELSPROBLEMS', 'should have error code') t.matchSnapshot(redactCwd(result), 'should output tree containing color info') _flatOptions.color = false @@ -492,7 +492,7 @@ t.test('ls', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing dev deps') _flatOptions.dev = false t.end() @@ -521,7 +521,7 @@ t.test('ls', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing only development deps') _flatOptions.only = null t.end() @@ -560,7 +560,7 @@ t.test('ls', (t) => { ...diffDepTypesNmFixture.node_modules, }, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing linked deps') _flatOptions.link = false t.end() @@ -596,7 +596,7 @@ t.test('ls', (t) => { b: t.fixture('symlink', '../b'), }, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing linked deps') _flatOptions.link = false t.end() @@ -625,7 +625,7 @@ t.test('ls', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing production deps') _flatOptions.production = false t.end() @@ -654,7 +654,7 @@ t.test('ls', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing only prod deps') _flatOptions.only = null t.end() @@ -683,7 +683,7 @@ t.test('ls', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree info with descriptions') _flatOptions.long = true t.end() @@ -714,7 +714,7 @@ t.test('ls', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing top-level deps with descriptions') _flatOptions.all = true _flatOptions.depth = Infinity @@ -727,7 +727,7 @@ t.test('ls', (t) => { prefix = t.testdir({ 'package.json': '{broken json', }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err, { code: 'EJSONPARSE' }, 'should throw EJSONPARSE error') t.matchSnapshot(redactCwd(result), 'should print empty result') t.end() @@ -736,7 +736,7 @@ t.test('ls', (t) => { t.test('empty location', (t) => { prefix = t.testdir({}) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'should not error out on empty locations') t.matchSnapshot(redactCwd(result), 'should print empty result') t.end() @@ -764,7 +764,7 @@ t.test('ls', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree signaling mismatching peer dep in problems') t.end() }) @@ -799,7 +799,7 @@ t.test('ls', (t) => { }, }, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree signaling mismatching peer dep in problems') _flatOptions.color = false t.end() @@ -828,7 +828,7 @@ t.test('ls', (t) => { }, }, }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err.code, 'ELSPROBLEMS', 'should have ELSPROBLEMS error code') t.match(err.message, /missing: b@\^1.0.0/, 'should list missing dep problem') t.matchSnapshot(redactCwd(result), 'should output parseable signaling missing peer dep in problems') @@ -846,7 +846,7 @@ t.test('ls', (t) => { }, }), }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err.code, 'ELSPROBLEMS', 'should have ELSPROBLEMS error code') t.match(err.message, 'missing: peer-dep@*, required by test-npm-ls@1.0.0', 'should have missing peer-dep error msg') t.matchSnapshot(redactCwd(result), 'should output tree signaling missing peer dep in problems') @@ -877,7 +877,7 @@ t.test('ls', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err.code, 'ELSPROBLEMS', 'should have ELSPROBLEMS error code') t.match(err.message, /invalid: optional-dep@1.0.0/, 'should have invalid dep error msg') t.matchSnapshot(redactCwd(result), 'should output tree with empty entry for missing optional deps') @@ -916,7 +916,7 @@ t.test('ls', (t) => { }, }, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref') t.end() @@ -954,7 +954,7 @@ t.test('ls', (t) => { }, }, }) - ls(['a'], (err) => { + ls.exec(['a'], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref') _flatOptions.color = false @@ -1002,7 +1002,7 @@ t.test('ls', (t) => { }, }, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref') t.end() @@ -1051,7 +1051,7 @@ t.test('ls', (t) => { }, }, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref') _flatOptions.all = true @@ -1101,7 +1101,7 @@ t.test('ls', (t) => { }, }, }) - ls(['@npmcli/b'], (err) => { + ls.exec(['@npmcli/b'], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref') _flatOptions.color = false @@ -1149,7 +1149,7 @@ t.test('ls', (t) => { }, }, }) - ls(['@npmcli/c'], (err) => { + ls.exec(['@npmcli/c'], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref') t.end() @@ -1193,7 +1193,7 @@ t.test('ls', (t) => { }, }) touchHiddenPackageLock(prefix) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing aliases') t.end() }) @@ -1239,7 +1239,7 @@ t.test('ls', (t) => { }, }) touchHiddenPackageLock(prefix) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output tree containing git refs') t.end() @@ -1283,7 +1283,7 @@ t.test('ls', (t) => { }, }), }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should NOT print git refs in output tree') t.end() @@ -1338,7 +1338,7 @@ t.test('ls', (t) => { }, }) touchHiddenPackageLock(prefix) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should not be printed in tree output') t.end() }) @@ -1374,7 +1374,7 @@ t.test('ls', (t) => { // mimics lib/npm.js globalDir getter but pointing to fixtures globalDir = resolve(fixtures, 'node_modules') - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should print tree and not mark top-level items extraneous') globalDir = 'MISSING_GLOBAL_DIR' _flatOptions.global = false @@ -1427,7 +1427,7 @@ t.test('ls', (t) => { }, }) - ls(['c'], (err) => { + ls.exec(['c'], (err) => { t.match(err.code, 'ELSPROBLEMS', 'should have ELSPROBLEMS error code') t.matchSnapshot(redactCwd(result), 'should print tree and not duplicate child of missing items') t.end() @@ -1471,12 +1471,12 @@ t.test('ls', (t) => { }, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'should NOT have ELSPROBLEMS error code') t.matchSnapshot(redactCwd(result), 'should list workspaces properly') // should also be able to filter out one of the workspaces - ls(['a'], (err) => { + ls.exec(['a'], (err) => { t.ifError(err, 'should NOT have ELSPROBLEMS error code when filter') t.matchSnapshot(redactCwd(result), 'should filter single workspace') @@ -1534,17 +1534,17 @@ t.test('ls', (t) => { }) t.plan(6) - ls(['a'], (err) => { + ls.exec(['a'], (err) => { t.ifError(err, 'should NOT have ELSPROBLEMS error code') t.matchSnapshot(redactCwd(result), 'should list a in top-level only') - ls(['d'], (err) => { + ls.exec(['d'], (err) => { t.ifError(err, 'should NOT have ELSPROBLEMS error code when filter') t.matchSnapshot(redactCwd(result), 'should print empty results msg') // if no --depth config is defined, should print path to dep _flatOptions.depth = null // default config value - ls(['d'], (err) => { + ls.exec(['d'], (err) => { t.ifError(err, 'should NOT have ELSPROBLEMS error code when filter') t.matchSnapshot(redactCwd(result), 'should print expected result') }) @@ -1576,7 +1576,7 @@ t.test('ls --parseable', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output parseable representation of dependencies structure') t.end() @@ -1587,7 +1587,7 @@ t.test('ls --parseable', (t) => { prefix = t.testdir({ ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err.code, 'ELSPROBLEMS', 'should have ELSPROBLEMS error code') t.matchSnapshot( redactCwd(err.message), @@ -1609,7 +1609,7 @@ t.test('ls --parseable', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.equal(err.code, 'ELSPROBLEMS', 'should have error code') t.matchSnapshot(redactCwd(result), 'should output containing problems info') t.end() @@ -1628,7 +1628,7 @@ t.test('ls --parseable', (t) => { }), ...simpleNmFixture, }) - ls(['lorem'], (err) => { + ls.exec(['lorem'], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output parseable contaning only occurrences of filtered by package') t.end() @@ -1647,7 +1647,7 @@ t.test('ls --parseable', (t) => { }), ...simpleNmFixture, }) - ls(['bar'], (err) => { + ls.exec(['bar'], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output parseable contaning only occurrences of filtered package') t.end() @@ -1675,7 +1675,7 @@ t.test('ls --parseable', (t) => { }, }, }) - ls(['bar@*', 'lorem@1.0.0'], (err) => { + ls.exec(['bar@*', 'lorem@1.0.0'], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output parseable contaning only occurrences of multiple filtered packages and their ancestors') t.end() @@ -1694,7 +1694,7 @@ t.test('ls --parseable', (t) => { }), ...simpleNmFixture, }) - ls(['notadep'], (err) => { + ls.exec(['notadep'], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output parseable output containing no dependencies info') t.equal( @@ -1721,7 +1721,7 @@ t.test('ls --parseable', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output parseable output containing only top-level dependencies') _flatOptions.all = true @@ -1744,7 +1744,7 @@ t.test('ls --parseable', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output tree containing only top-level dependencies') _flatOptions.all = true @@ -1767,7 +1767,7 @@ t.test('ls --parseable', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output parseable containing top-level deps and their deps only') _flatOptions.all = true @@ -1788,7 +1788,7 @@ t.test('ls --parseable', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err, { code: 'ELSPROBLEMS' }, 'should list dep problems') t.matchSnapshot(redactCwd(result), 'should output parseable containing top-level deps and their deps only') t.end() @@ -1817,7 +1817,7 @@ t.test('ls --parseable', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing dev deps') _flatOptions.dev = false t.end() @@ -1846,7 +1846,7 @@ t.test('ls --parseable', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing only development deps') _flatOptions.only = null t.end() @@ -1885,7 +1885,7 @@ t.test('ls --parseable', (t) => { ...diffDepTypesNmFixture.node_modules, }, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing linked deps') _flatOptions.link = false t.end() @@ -1914,7 +1914,7 @@ t.test('ls --parseable', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing production deps') _flatOptions.production = false t.end() @@ -1943,7 +1943,7 @@ t.test('ls --parseable', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing only prod deps') _flatOptions.only = null t.end() @@ -1972,7 +1972,7 @@ t.test('ls --parseable', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree info with descriptions') _flatOptions.long = true t.end() @@ -1990,7 +1990,7 @@ t.test('ls --parseable', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.equal(err.code, 'ELSPROBLEMS', 'should have error code') t.match(redactCwd(err.message), 'extraneous: lorem@1.0.0 {CWD}/ls-ls-parseable--long-with-extraneous-deps/node_modules/lorem', 'should have error code') t.matchSnapshot(redactCwd(result), 'should output long parseable output with extraneous info') @@ -2011,7 +2011,7 @@ t.test('ls --parseable', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err, { code: 'ELSPROBLEMS' }, 'should list dep problems') t.matchSnapshot(redactCwd(result), 'should output parseable result containing EXTRANEOUS/INVALID labels') _flatOptions.long = false @@ -2051,7 +2051,7 @@ t.test('ls --parseable', (t) => { ...diffDepTypesNmFixture.node_modules, }, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.matchSnapshot(redactCwd(result), 'should output parseable results with symlink targets') _flatOptions.long = false @@ -2083,7 +2083,7 @@ t.test('ls --parseable', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing top-level deps with descriptions') _flatOptions.all = true _flatOptions.depth = Infinity @@ -2096,7 +2096,7 @@ t.test('ls --parseable', (t) => { prefix = t.testdir({ 'package.json': '{broken json', }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err, { code: 'EJSONPARSE' }, 'should throw EJSONPARSE error') t.matchSnapshot(redactCwd(result), 'should print empty result') t.end() @@ -2105,7 +2105,7 @@ t.test('ls --parseable', (t) => { t.test('empty location', (t) => { prefix = t.testdir({}) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'should not error out on empty locations') t.matchSnapshot(redactCwd(result), 'should print empty result') t.end() @@ -2133,7 +2133,7 @@ t.test('ls --parseable', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output parseable signaling missing peer dep in problems') t.end() }) @@ -2161,7 +2161,7 @@ t.test('ls --parseable', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err.code, 'ELSPROBLEMS', 'should have ELSPROBLEMS error code') t.match(err.message, /invalid: optional-dep@1.0.0/, 'should have invalid dep error msg') t.matchSnapshot(redactCwd(result), 'should output parseable with empty entry for missing optional deps') @@ -2199,7 +2199,7 @@ t.test('ls --parseable', (t) => { }, }, }) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should print tree output omitting deduped ref') t.end() }) @@ -2238,7 +2238,7 @@ t.test('ls --parseable', (t) => { }, }) touchHiddenPackageLock(prefix) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing aliases') t.end() }) @@ -2283,7 +2283,7 @@ t.test('ls --parseable', (t) => { }, }) touchHiddenPackageLock(prefix) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should output tree containing git refs') t.end() }) @@ -2337,7 +2337,7 @@ t.test('ls --parseable', (t) => { }, }) touchHiddenPackageLock(prefix) - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should not be printed in tree output') t.end() }) @@ -2373,7 +2373,7 @@ t.test('ls --parseable', (t) => { // mimics lib/npm.js globalDir getter but pointing to fixtures globalDir = resolve(fixtures, 'node_modules') - ls([], () => { + ls.exec([], () => { t.matchSnapshot(redactCwd(result), 'should print parseable output for global deps') globalDir = 'MISSING_GLOBAL_DIR' _flatOptions.global = false @@ -2400,7 +2400,7 @@ t.test('ls --json', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.deepEqual( jsonParse(result), @@ -2431,7 +2431,7 @@ t.test('ls --json', (t) => { prefix = t.testdir({ ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err, { code: 'ELSPROBLEMS' }, 'should list dep problems') t.deepEqual( jsonParse(result), @@ -2487,7 +2487,7 @@ t.test('ls --json', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.equal( redactCwd(err.message), 'extraneous: lorem@1.0.0 {CWD}/ls-ls-json-extraneous-deps/node_modules/lorem', @@ -2542,7 +2542,7 @@ t.test('ls --json', (t) => { }), ...simpleNmFixture, }) - ls(['lorem'], (err) => { + ls.exec(['lorem'], (err) => { t.ifError(err, 'npm ls') t.deepEqual( jsonParse(result), @@ -2578,7 +2578,7 @@ t.test('ls --json', (t) => { }), ...simpleNmFixture, }) - ls(['bar'], (err) => { + ls.exec(['bar'], (err) => { t.ifError(err, 'npm ls') t.deepEqual( jsonParse(result), @@ -2623,7 +2623,7 @@ t.test('ls --json', (t) => { }, }, }) - ls(['bar@*', 'lorem@1.0.0'], (err) => { + ls.exec(['bar@*', 'lorem@1.0.0'], (err) => { t.ifError(err, 'npm ls') t.deepEqual( jsonParse(result), @@ -2662,7 +2662,7 @@ t.test('ls --json', (t) => { }), ...simpleNmFixture, }) - ls(['notadep'], (err) => { + ls.exec(['notadep'], (err) => { t.ifError(err, 'npm ls') t.deepEqual( jsonParse(result), @@ -2696,7 +2696,7 @@ t.test('ls --json', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.deepEqual( jsonParse(result), @@ -2734,7 +2734,7 @@ t.test('ls --json', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.deepEqual( jsonParse(result), @@ -2772,7 +2772,7 @@ t.test('ls --json', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'npm ls') t.deepEqual( jsonParse(result), @@ -2813,7 +2813,7 @@ t.test('ls --json', (t) => { }), ...simpleNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err, { code: 'ELSPROBLEMS' }, 'should list dep problems') t.deepEqual( jsonParse(result), @@ -2882,7 +2882,7 @@ t.test('ls --json', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -2929,7 +2929,7 @@ t.test('ls --json', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -2986,7 +2986,7 @@ t.test('ls --json', (t) => { ...diffDepTypesNmFixture.node_modules, }, }) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -3028,7 +3028,7 @@ t.test('ls --json', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -3069,7 +3069,7 @@ t.test('ls --json', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -3182,7 +3182,7 @@ t.test('ls --json', (t) => { }, }), }) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -3239,7 +3239,7 @@ t.test('ls --json', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -3377,7 +3377,7 @@ t.test('ls --json', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -3460,7 +3460,7 @@ t.test('ls --json', (t) => { prefix = t.testdir({ 'package.json': '{broken json', }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err.message, 'Failed to parse root package.json', 'should have missin root package.json msg') t.match(err.code, 'EJSONPARSE', 'should have EJSONPARSE error code') t.deepEqual( @@ -3479,7 +3479,7 @@ t.test('ls --json', (t) => { t.test('empty location', (t) => { prefix = t.testdir({}) - ls([], (err) => { + ls.exec([], (err) => { t.ifError(err, 'should not error out on empty locations') t.deepEqual( jsonParse(result), @@ -3511,7 +3511,7 @@ t.test('ls --json', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err.code, 'ELSPROBLEMS', 'Should have ELSPROBLEMS error code') t.deepEqual( jsonParse(result), @@ -3571,7 +3571,7 @@ t.test('ls --json', (t) => { }), ...diffDepTypesNmFixture, }) - ls([], (err) => { + ls.exec([], (err) => { t.match(err.code, 'ELSPROBLEMS', 'should have ELSPROBLEMS error code') t.match(err.message, /invalid: optional-dep@1.0.0/, 'should have invalid dep error msg') t.deepEqual( @@ -3643,7 +3643,7 @@ t.test('ls --json', (t) => { }, }, }) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -3701,7 +3701,7 @@ t.test('ls --json', (t) => { }, }) touchHiddenPackageLock(prefix) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -3761,7 +3761,7 @@ t.test('ls --json', (t) => { }, }) touchHiddenPackageLock(prefix) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -3845,7 +3845,7 @@ t.test('ls --json', (t) => { }, }) touchHiddenPackageLock(prefix) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -3870,7 +3870,7 @@ t.test('ls --json', (t) => { version: '1.0.0', }), }) - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { @@ -3913,7 +3913,7 @@ t.test('ls --json', (t) => { // mimics lib/npm.js globalDir getter but pointing to fixtures globalDir = resolve(fixtures, 'node_modules') - ls([], () => { + ls.exec([], () => { t.deepEqual( jsonParse(result), { diff --git a/deps/npm/test/lib/npm.js b/deps/npm/test/lib/npm.js index 9fd9888b97..1f7a54e228 100644 --- a/deps/npm/test/lib/npm.js +++ b/deps/npm/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' @@ -16,12 +15,12 @@ for (const env of Object.keys(process.env).filter(e => /^npm_/.test(e))) { 'should match "npm test" or "npm run test"' ) } else - t.match(process.env[env], 'run-script') + t.match(process.env[env], /^(run)|(run-script)|(exec)$/) } 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,17 +300,17 @@ 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) => { if (er) throw er - t.same(consoleLogs, [[require('../../lib/ls.js').usage]], 'print usage') + t.same(consoleLogs, [[npm.commands.ll.usage]], 'print usage') consoleLogs.length = 0 npm.config.set('usage', false) - t.equal(npm.commands.ll, npm.commands.la, 'same command, different name') + t.equal(npm.commands.ll, npm.commands.ll, 'same command, different name') logs.length = 0 }) @@ -352,13 +349,15 @@ t.test('npm.load', t => { t.test('loading as main will load the cli', t => { const { spawn } = require('child_process') const npm = require.resolve('../../lib/npm.js') + const LS = require('../../lib/ls.js') + const ls = new LS({}) const p = spawn(process.execPath, [npm, 'ls', '-h']) const out = [] p.stdout.on('data', c => out.push(c)) p.on('close', (code, signal) => { t.equal(code, 0) t.equal(signal, null) - t.equal(Buffer.concat(out).toString().trim(), require('../../lib/ls.js').usage) + t.equal(Buffer.concat(out).toString().trim(), ls.usage) t.end() }) }) diff --git a/deps/npm/test/lib/org.js b/deps/npm/test/lib/org.js index 1e8aabc1d7..d21df85d64 100644 --- a/deps/npm/test/lib/org.js +++ b/deps/npm/test/lib/org.js @@ -39,14 +39,14 @@ const libnpmorg = { }, } -const org = requireInject('../../lib/org.js', { - '../../lib/npm.js': npm, +const Org = requireInject('../../lib/org.js', { '../../lib/utils/otplease.js': async (opts, fn) => fn(opts), '../../lib/utils/output.js': (msg) => { output.push(msg) }, libnpmorg, }) +const org = new Org(npm) test('completion', async t => { const completion = (argv) => @@ -67,7 +67,7 @@ test('completion', async t => { }) test('npm org - invalid subcommand', t => { - return org(['foo'], (err) => { + org.exec(['foo'], (err) => { t.match(err, /npm org set/, 'prints usage information') t.end() }) @@ -79,7 +79,7 @@ test('npm org add', t => { output.length = 0 }) - return org(['add', 'orgname', 'username'], (err) => { + org.exec(['add', 'orgname', 'username'], (err) => { if (err) throw err @@ -100,7 +100,7 @@ test('npm org add - no org', t => { output.length = 0 }) - return org(['add', '', 'username'], (err) => { + org.exec(['add', '', 'username'], (err) => { t.match(err, /`orgname` is required/, 'returns the correct error') t.end() }) @@ -112,7 +112,7 @@ test('npm org add - no user', t => { output.length = 0 }) - return org(['add', 'orgname', ''], (err) => { + org.exec(['add', 'orgname', ''], (err) => { t.match(err, /`username` is required/, 'returns the correct error') t.end() }) @@ -124,7 +124,7 @@ test('npm org add - invalid role', t => { output.length = 0 }) - return org(['add', 'orgname', 'username', 'person'], (err) => { + org.exec(['add', 'orgname', 'username', 'person'], (err) => { t.match(err, /`role` must be one of/, 'returns the correct error') t.end() }) @@ -138,7 +138,7 @@ test('npm org add - more users', t => { output.length = 0 }) - return org(['add', 'orgname', 'username'], (err) => { + org.exec(['add', 'orgname', 'username'], (err) => { if (err) throw err @@ -161,7 +161,7 @@ test('npm org add - json output', t => { output.length = 0 }) - return org(['add', 'orgname', 'username'], (err) => { + org.exec(['add', 'orgname', 'username'], (err) => { if (err) throw err @@ -191,7 +191,7 @@ test('npm org add - parseable output', t => { output.length = 0 }) - return org(['add', 'orgname', 'username'], (err) => { + org.exec(['add', 'orgname', 'username'], (err) => { if (err) throw err @@ -217,7 +217,7 @@ test('npm org add - silent output', t => { output.length = 0 }) - return org(['add', 'orgname', 'username'], (err) => { + org.exec(['add', 'orgname', 'username'], (err) => { if (err) throw err @@ -239,7 +239,7 @@ test('npm org rm', t => { output.length = 0 }) - return org(['rm', 'orgname', 'username'], (err) => { + org.exec(['rm', 'orgname', 'username'], (err) => { if (err) throw err @@ -264,7 +264,7 @@ test('npm org rm - no org', t => { output.length = 0 }) - return org(['rm', '', 'username'], (err) => { + org.exec(['rm', '', 'username'], (err) => { t.match(err, /`orgname` is required/, 'threw the correct error') t.end() }) @@ -277,7 +277,7 @@ test('npm org rm - no user', t => { output.length = 0 }) - return org(['rm', 'orgname'], (err) => { + org.exec(['rm', 'orgname'], (err) => { t.match(err, /`username` is required/, 'threw the correct error') t.end() }) @@ -295,7 +295,7 @@ test('npm org rm - one user left', t => { output.length = 0 }) - return org(['rm', 'orgname', 'username'], (err) => { + org.exec(['rm', 'orgname', 'username'], (err) => { if (err) throw err @@ -322,7 +322,7 @@ test('npm org rm - json output', t => { output.length = 0 }) - return org(['rm', 'orgname', 'username'], (err) => { + org.exec(['rm', 'orgname', 'username'], (err) => { if (err) throw err @@ -354,7 +354,7 @@ test('npm org rm - parseable output', t => { output.length = 0 }) - return org(['rm', 'orgname', 'username'], (err) => { + org.exec(['rm', 'orgname', 'username'], (err) => { if (err) throw err @@ -384,7 +384,7 @@ test('npm org rm - silent output', t => { output.length = 0 }) - return org(['rm', 'orgname', 'username'], (err) => { + org.exec(['rm', 'orgname', 'username'], (err) => { if (err) throw err @@ -414,7 +414,7 @@ test('npm org ls', t => { output.length = 0 }) - return org(['ls', 'orgname'], (err) => { + org.exec(['ls', 'orgname'], (err) => { if (err) throw err @@ -441,7 +441,7 @@ test('npm org ls - user filter', t => { output.length = 0 }) - return org(['ls', 'orgname', 'username'], (err) => { + org.exec(['ls', 'orgname', 'username'], (err) => { if (err) throw err @@ -466,7 +466,7 @@ test('npm org ls - user filter, missing user', t => { output.length = 0 }) - return org(['ls', 'orgname', 'username'], (err) => { + org.exec(['ls', 'orgname', 'username'], (err) => { if (err) throw err @@ -487,7 +487,7 @@ test('npm org ls - no org', t => { output.length = 0 }) - return org(['ls'], (err) => { + org.exec(['ls'], (err) => { t.match(err, /`orgname` is required/, 'throws the correct error') t.end() }) @@ -507,7 +507,7 @@ test('npm org ls - json output', t => { output.length = 0 }) - return org(['ls', 'orgname'], (err) => { + org.exec(['ls', 'orgname'], (err) => { if (err) throw err @@ -534,7 +534,7 @@ test('npm org ls - parseable output', t => { output.length = 0 }) - return org(['ls', 'orgname'], (err) => { + org.exec(['ls', 'orgname'], (err) => { if (err) throw err @@ -566,7 +566,7 @@ test('npm org ls - silent output', t => { output.length = 0 }) - return org(['ls', 'orgname'], (err) => { + org.exec(['ls', 'orgname'], (err) => { if (err) throw err diff --git a/deps/npm/test/lib/outdated.js b/deps/npm/test/lib/outdated.js index da53b6031d..aa8a1bcb6b 100644 --- a/deps/npm/test/lib/outdated.js +++ b/deps/npm/test/lib/outdated.js @@ -92,19 +92,18 @@ const globalDir = t.testdir({ }, }) -const outdated = (dir, opts) => requireInject( - '../../lib/outdated.js', - { - '../../lib/npm.js': { - prefix: dir, - globalDir: `${globalDir}/node_modules`, - flatOptions: opts, - }, +const outdated = (dir, opts) => { + const Outdated = requireInject('../../lib/outdated.js', { pacote: { packument, }, - } -) + }) + return new Outdated({ + prefix: dir, + globalDir: `${globalDir}/node_modules`, + flatOptions: opts, + }) +} t.beforeEach(cleanLogs) @@ -180,7 +179,7 @@ t.test('should display outdated deps', t => { t.test('outdated global', t => { outdated(null, { global: true, - })([], () => { + }).exec([], () => { t.matchSnapshot(logs) t.end() }) @@ -190,7 +189,7 @@ t.test('should display outdated deps', t => { outdated(testDir, { global: false, color: true, - })([], () => { + }).exec([], () => { t.matchSnapshot(logs) t.end() }) @@ -201,7 +200,7 @@ t.test('should display outdated deps', t => { global: false, color: true, omit: ['dev'], - })([], () => { + }).exec([], () => { t.matchSnapshot(logs) t.end() }) @@ -212,7 +211,7 @@ t.test('should display outdated deps', t => { global: false, color: true, omit: ['dev', 'peer'], - })([], () => { + }).exec([], () => { t.matchSnapshot(logs) t.end() }) @@ -223,7 +222,7 @@ t.test('should display outdated deps', t => { global: false, color: true, omit: ['prod'], - })([], () => { + }).exec([], () => { t.matchSnapshot(logs) t.end() }) @@ -233,7 +232,7 @@ t.test('should display outdated deps', t => { outdated(testDir, { global: false, long: true, - })([], () => { + }).exec([], () => { t.matchSnapshot(logs) t.end() }) @@ -243,7 +242,7 @@ t.test('should display outdated deps', t => { outdated(testDir, { global: false, json: true, - })([], () => { + }).exec([], () => { t.matchSnapshot(logs) t.end() }) @@ -254,7 +253,7 @@ t.test('should display outdated deps', t => { global: false, json: true, long: true, - })([], () => { + }).exec([], () => { t.matchSnapshot(logs) t.end() }) @@ -264,7 +263,7 @@ t.test('should display outdated deps', t => { outdated(testDir, { global: false, parseable: true, - })([], () => { + }).exec([], () => { t.matchSnapshot(logs) t.end() }) @@ -275,7 +274,7 @@ t.test('should display outdated deps', t => { global: false, parseable: true, long: true, - })([], () => { + }).exec([], () => { t.matchSnapshot(logs) t.end() }) @@ -284,7 +283,7 @@ t.test('should display outdated deps', t => { t.test('outdated --all', t => { outdated(testDir, { all: true, - })([], () => { + }).exec([], () => { t.matchSnapshot(logs) t.end() }) @@ -293,7 +292,7 @@ t.test('should display outdated deps', t => { t.test('outdated specific dep', t => { outdated(testDir, { global: false, - })(['alpha'], () => { + }).exec(['alpha'], () => { t.matchSnapshot(logs) t.end() }) @@ -323,7 +322,7 @@ t.test('should return if no outdated deps', t => { outdated(testDir, { global: false, - })([], () => { + }).exec([], () => { t.equals(logs.length, 0, 'no logs') t.end() }) @@ -350,7 +349,7 @@ t.test('throws if error with a dep', t => { outdated(testDir, { global: false, - })([], (err) => { + }).exec([], (err) => { t.equals(err.message, 'There is an error with this package.') t.end() }) @@ -370,7 +369,7 @@ t.test('should skip missing non-prod deps', t => { outdated(testDir, { global: false, - })([], () => { + }).exec([], () => { t.equals(logs.length, 0, 'no logs') t.end() }) @@ -395,7 +394,7 @@ t.test('should skip invalid pkg ranges', t => { }, }) - outdated(testDir, {})([], () => { + outdated(testDir, {}).exec([], () => { t.equals(logs.length, 0, 'no logs') t.end() }) @@ -420,7 +419,7 @@ t.test('should skip git specs', t => { }, }) - outdated(testDir, {})([], () => { + outdated(testDir, {}).exec([], () => { t.equals(logs.length, 0, 'no logs') t.end() }) diff --git a/deps/npm/test/lib/owner.js b/deps/npm/test/lib/owner.js index aa5e3ee637..4f8f430886 100644 --- a/deps/npm/test/lib/owner.js +++ b/deps/npm/test/lib/owner.js @@ -15,7 +15,6 @@ const mocks = { npmlog, 'npm-registry-fetch': npmFetch, pacote, - '../../lib/npm.js': npm, '../../lib/utils/output.js': (...msg) => { result += msg.join('\n') }, @@ -31,7 +30,8 @@ const npmcliMaintainers = [ { email: 'i@izs.me', name: 'isaacs' }, ] -const owner = requireInject('../../lib/owner.js', mocks) +const Owner = requireInject('../../lib/owner.js', mocks) +const owner = new Owner(npm) t.test('owner no args', t => { result = '' @@ -39,7 +39,7 @@ t.test('owner no args', t => { result = '' }) - owner([], err => { + owner.exec([], err => { t.equal( err.message, 'usage instructions', @@ -73,7 +73,7 @@ t.test('owner ls no args', t => { readLocalPkgResponse = null }) - owner(['ls'], err => { + owner.exec(['ls'], err => { t.ifError(err, 'npm owner ls no args') t.matchSnapshot(result, 'should output owners of cwd package') }) @@ -86,7 +86,7 @@ t.test('owner ls no args no cwd package', t => { npmlog.error = noop }) - owner(['ls'], err => { + owner.exec(['ls'], err => { t.equal( err.message, 'usage instructions', @@ -115,7 +115,7 @@ t.test('owner ls fails to retrieve packument', t => { pacote.packument = noop }) - owner(['ls'], err => { + owner.exec(['ls'], err => { t.match( err, /ERR/, @@ -145,7 +145,7 @@ t.test('owner ls <pkg>', t => { pacote.packument = noop }) - owner(['ls', '@npmcli/map-workspaces'], err => { + owner.exec(['ls', '@npmcli/map-workspaces'], err => { t.ifError(err, 'npm owner ls <pkg>') t.matchSnapshot(result, 'should output owners of <pkg>') }) @@ -161,7 +161,7 @@ t.test('owner ls <pkg> no maintainers', t => { pacote.packument = noop }) - owner(['ls', '@npmcli/map-workspaces'], err => { + owner.exec(['ls', '@npmcli/map-workspaces'], err => { t.ifError(err, 'npm owner ls <pkg> no maintainers') t.equal(result, 'no admin found', 'should output no admint found msg') t.end() @@ -232,7 +232,7 @@ t.test('owner add <user> <pkg>', t => { pacote.packument = noop }) - owner(['add', 'foo', '@npmcli/map-workspaces'], err => { + owner.exec(['add', 'foo', '@npmcli/map-workspaces'], err => { t.ifError(err, 'npm owner add <user> <pkg>') t.equal(result, '+ foo (@npmcli/map-workspaces)', 'should output add result') }) @@ -265,7 +265,7 @@ t.test('owner add <user> cwd package', t => { pacote.packument = noop }) - owner(['add', 'foo'], err => { + owner.exec(['add', 'foo'], err => { t.ifError(err, 'npm owner add <user> cwd package') t.equal(result, '+ foo (@npmcli/map-workspaces)', 'should output add result') t.end() @@ -308,7 +308,7 @@ t.test('owner add <user> <pkg> already an owner', t => { pacote.packument = noop }) - owner(['add', 'ruyadorno', '@npmcli/map-workspaces'], err => { + owner.exec(['add', 'ruyadorno', '@npmcli/map-workspaces'], err => { t.ifError(err, 'npm owner add <user> <pkg> already an owner') }) }) @@ -336,7 +336,7 @@ t.test('owner add <user> <pkg> fails to retrieve user', t => { pacote.packument = noop }) - owner(['add', 'foo', '@npmcli/map-workspaces'], err => { + owner.exec(['add', 'foo', '@npmcli/map-workspaces'], err => { t.match( err, /Error: Couldn't get user data for foo: {"ok":false}/, @@ -377,7 +377,7 @@ t.test('owner add <user> <pkg> fails to PUT updates', t => { pacote.packument = noop }) - owner(['add', 'foo', '@npmcli/map-workspaces'], err => { + owner.exec(['add', 'foo', '@npmcli/map-workspaces'], err => { t.match( err.message, /Failed to update package/, @@ -417,7 +417,7 @@ t.test('owner add <user> <pkg> fails to retrieve user info', t => { pacote.packument = noop }) - owner(['add', 'foo', '@npmcli/map-workspaces'], err => { + owner.exec(['add', 'foo', '@npmcli/map-workspaces'], err => { t.match( err.message, "I'm a teapot", @@ -453,7 +453,7 @@ t.test('owner add <user> <pkg> no previous maintainers property from server', t pacote.packument = noop }) - owner(['add', 'foo', '@npmcli/no-owners-pkg'], err => { + owner.exec(['add', 'foo', '@npmcli/no-owners-pkg'], err => { t.ifError(err, 'npm owner add <user> <pkg>') t.equal(result, '+ foo (@npmcli/no-owners-pkg)', 'should output add result') t.end() @@ -466,7 +466,7 @@ t.test('owner add no user', t => { result = '' }) - owner(['add'], err => { + owner.exec(['add'], err => { t.equal( err.message, 'usage instructions', @@ -482,7 +482,7 @@ t.test('owner add <user> no cwd package', t => { result = '' }) - owner(['add', 'foo'], err => { + owner.exec(['add', 'foo'], err => { t.equal( err.message, 'usage instructions', @@ -549,7 +549,7 @@ t.test('owner rm <user> <pkg>', t => { pacote.packument = noop }) - owner(['rm', 'ruyadorno', '@npmcli/map-workspaces'], err => { + owner.exec(['rm', 'ruyadorno', '@npmcli/map-workspaces'], err => { t.ifError(err, 'npm owner rm <user> <pkg>') t.equal(result, '- ruyadorno (@npmcli/map-workspaces)', 'should output rm result') }) @@ -589,7 +589,7 @@ t.test('owner rm <user> <pkg> not a current owner', t => { pacote.packument = noop }) - owner(['rm', 'foo', '@npmcli/map-workspaces'], err => { + owner.exec(['rm', 'foo', '@npmcli/map-workspaces'], err => { t.ifError(err, 'npm owner rm <user> <pkg> not a current owner') }) }) @@ -621,7 +621,7 @@ t.test('owner rm <user> cwd package', t => { pacote.packument = noop }) - owner(['rm', 'ruyadorno'], err => { + owner.exec(['rm', 'ruyadorno'], err => { t.ifError(err, 'npm owner rm <user> cwd package') t.equal(result, '- ruyadorno (@npmcli/map-workspaces)', 'should output rm result') t.end() @@ -656,7 +656,7 @@ t.test('owner rm <user> only user', t => { pacote.packument = noop }) - owner(['rm', 'ruyadorno'], err => { + owner.exec(['rm', 'ruyadorno'], err => { t.equal( err.message, 'Cannot remove all owners of a package. Add someone else first.', @@ -673,7 +673,7 @@ t.test('owner rm no user', t => { result = '' }) - owner(['rm'], err => { + owner.exec(['rm'], err => { t.equal( err.message, 'usage instructions', @@ -689,7 +689,7 @@ t.test('owner rm <user> no cwd package', t => { result = '' }) - owner(['rm', 'foo'], err => { + owner.exec(['rm', 'foo'], err => { t.equal( err.message, 'usage instructions', @@ -700,10 +700,8 @@ t.test('owner rm <user> no cwd package', t => { }) t.test('completion', async t => { - const { completion } = owner - const testComp = async (argv, expect) => { - const res = await completion({ conf: { argv: { remain: argv } } }) + const res = await owner.completion({ conf: { argv: { remain: argv } } }) t.strictSame(res, expect, argv.join(' ')) } @@ -730,7 +728,7 @@ t.test('completion', async t => { pacote.packument = noop }) - const res = await completion({ conf: { argv: { remain: ['npm', 'owner', 'rm'] } } }) + const res = await owner.completion({ conf: { argv: { remain: ['npm', 'owner', 'rm'] } } }) t.strictSame(res, ['nlf', 'ruyadorno', 'darcyclarke', 'isaacs'], 'should return list of current owners' @@ -738,7 +736,7 @@ t.test('completion', async t => { }) t.test('completion npm owner rm no cwd package', async t => { - const res = await completion({ conf: { argv: { remain: ['npm', 'owner', 'rm'] } } }) + const res = await owner.completion({ conf: { argv: { remain: ['npm', 'owner', 'rm'] } } }) t.strictSame(res, [], 'should have no owners to autocomplete if not cwd package') t.end() }) @@ -757,7 +755,7 @@ t.test('completion', async t => { pacote.packument = noop }) - const res = await completion({ conf: { argv: { remain: ['npm', 'owner', 'rm'] } } }) + const res = await owner.completion({ conf: { argv: { remain: ['npm', 'owner', 'rm'] } } }) t.strictSame(res, [], 'should return no owners if not found') }) diff --git a/deps/npm/test/lib/pack.js b/deps/npm/test/lib/pack.js index 851174d259..73a19baa3e 100644 --- a/deps/npm/test/lib/pack.js +++ b/deps/npm/test/lib/pack.js @@ -17,15 +17,8 @@ t.afterEach(cb => { }) t.test('should pack current directory with no arguments', (t) => { - const pack = requireInject('../../lib/pack.js', { + const Pack = requireInject('../../lib/pack.js', { '../../lib/utils/output.js': output, - '../../lib/npm.js': { - flatOptions: { - unicode: false, - json: false, - dryRun: false, - }, - }, libnpmpack, npmlog: { notice: () => {}, @@ -33,13 +26,21 @@ t.test('should pack current directory with no arguments', (t) => { clearProgress: () => {}, }, }) + const pack = new Pack({ + flatOptions: { + unicode: false, + json: false, + dryRun: false, + }, + }) - return pack([], er => { + pack.exec([], er => { if (er) throw er const filename = `npm-${require('../../package.json').version}.tgz` t.strictSame(OUTPUT, [[filename]]) + t.end() }) }) @@ -51,15 +52,8 @@ t.test('should pack given directory', (t) => { }, null, 2), }) - const pack = requireInject('../../lib/pack.js', { + const Pack = requireInject('../../lib/pack.js', { '../../lib/utils/output.js': output, - '../../lib/npm.js': { - flatOptions: { - unicode: true, - json: true, - dryRun: true, - }, - }, libnpmpack, npmlog: { notice: () => {}, @@ -67,13 +61,21 @@ t.test('should pack given directory', (t) => { clearProgress: () => {}, }, }) + const pack = new Pack({ + flatOptions: { + unicode: true, + json: true, + dryRun: true, + }, + }) - return pack([testDir], er => { + pack.exec([testDir], er => { if (er) throw er const filename = 'my-cool-pkg-1.0.0.tgz' t.strictSame(OUTPUT, [[filename]]) + t.end() }) }) @@ -85,15 +87,8 @@ t.test('should pack given directory for scoped package', (t) => { }, null, 2), }) - const pack = requireInject('../../lib/pack.js', { + const Pack = requireInject('../../lib/pack.js', { '../../lib/utils/output.js': output, - '../../lib/npm.js': { - flatOptions: { - unicode: true, - json: true, - dryRun: true, - }, - }, libnpmpack, npmlog: { notice: () => {}, @@ -101,18 +96,26 @@ t.test('should pack given directory for scoped package', (t) => { clearProgress: () => {}, }, }) + const pack = new Pack({ + flatOptions: { + unicode: true, + json: true, + dryRun: true, + }, + }) - return pack([testDir], er => { + return pack.exec([testDir], er => { if (er) throw er const filename = 'cool-my-pkg-1.0.0.tgz' t.strictSame(OUTPUT, [[filename]]) + t.end() }) }) t.test('should log pack contents', (t) => { - const pack = requireInject('../../lib/pack.js', { + const Pack = requireInject('../../lib/pack.js', { '../../lib/utils/output.js': output, '../../lib/utils/tar.js': { ...require('../../lib/utils/tar.js'), @@ -120,13 +123,6 @@ t.test('should log pack contents', (t) => { t.ok(true, 'logTar is called') }, }, - '../../lib/npm.js': { - flatOptions: { - unicode: false, - json: false, - dryRun: false, - }, - }, libnpmpack, npmlog: { notice: () => {}, @@ -134,12 +130,20 @@ t.test('should log pack contents', (t) => { clearProgress: () => {}, }, }) + const pack = new Pack({ + flatOptions: { + unicode: false, + json: false, + dryRun: false, + }, + }) - return pack([], er => { + pack.exec([], er => { if (er) throw er const filename = `npm-${require('../../package.json').version}.tgz` t.strictSame(OUTPUT, [[filename]]) + t.end() }) }) diff --git a/deps/npm/test/lib/ping.js b/deps/npm/test/lib/ping.js index a185919ddd..cf47530749 100644 --- a/deps/npm/test/lib/ping.js +++ b/deps/npm/test/lib/ping.js @@ -6,8 +6,7 @@ test('pings', (t) => { const flatOptions = { registry: 'https://registry.npmjs.org' } let noticeCalls = 0 - const ping = requireInject('../../lib/ping.js', { - '../../lib/npm.js': { flatOptions }, + const Ping = requireInject('../../lib/ping.js', { '../../lib/utils/ping.js': function (spec) { t.equal(spec, flatOptions, 'passes flatOptions') return {} @@ -25,8 +24,9 @@ test('pings', (t) => { }, }, }) + const ping = new Ping({ flatOptions }) - ping([], (err) => { + ping.exec([], (err) => { t.equal(noticeCalls, 2, 'should have logged 2 lines') t.ifError(err, 'npm ping') t.ok('should be able to ping') @@ -39,8 +39,7 @@ test('pings and logs details', (t) => { const flatOptions = { registry: 'https://registry.npmjs.org' } const details = { extra: 'data' } let noticeCalls = 0 - const ping = requireInject('../../lib/ping.js', { - '../../lib/npm.js': { flatOptions }, + const Ping = requireInject('../../lib/ping.js', { '../../lib/utils/ping.js': function (spec) { t.equal(spec, flatOptions, 'passes flatOptions') return details @@ -62,8 +61,9 @@ test('pings and logs details', (t) => { }, }, }) + const ping = new Ping({ flatOptions }) - ping([], (err) => { + ping.exec([], (err) => { t.equal(noticeCalls, 3, 'should have logged 3 lines') t.ifError(err, 'npm ping') t.ok('should be able to ping') @@ -76,8 +76,7 @@ test('pings and returns json', (t) => { const flatOptions = { registry: 'https://registry.npmjs.org', json: true } const details = { extra: 'data' } let noticeCalls = 0 - const ping = requireInject('../../lib/ping.js', { - '../../lib/npm.js': { flatOptions }, + const Ping = requireInject('../../lib/ping.js', { '../../lib/utils/ping.js': function (spec) { t.equal(spec, flatOptions, 'passes flatOptions') return details @@ -101,8 +100,9 @@ test('pings and returns json', (t) => { }, }, }) + const ping = new Ping({ flatOptions }) - ping([], (err) => { + ping.exec([], (err) => { t.equal(noticeCalls, 2, 'should have logged 2 lines') t.ifError(err, 'npm ping') t.ok('should be able to ping') diff --git a/deps/npm/test/lib/prefix.js b/deps/npm/test/lib/prefix.js index 83e2d63680..dfb50f174f 100644 --- a/deps/npm/test/lib/prefix.js +++ b/deps/npm/test/lib/prefix.js @@ -5,14 +5,14 @@ test('prefix', (t) => { t.plan(3) const dir = '/prefix/dir' - const prefix = requireInject('../../lib/prefix.js', { - '../../lib/npm.js': { prefix: dir }, + const Prefix = requireInject('../../lib/prefix.js', { '../../lib/utils/output.js': (output) => { t.equal(output, dir, 'prints the correct directory') }, }) + const prefix = new Prefix({ prefix: dir }) - prefix([], (err) => { + prefix.exec([], (err) => { t.ifError(err, 'npm prefix') t.ok('should have printed directory') }) diff --git a/deps/npm/test/lib/profile.js b/deps/npm/test/lib/profile.js index 3b2e140036..743ba2d687 100644 --- a/deps/npm/test/lib/profile.js +++ b/deps/npm/test/lib/profile.js @@ -32,7 +32,6 @@ const mocks = { .join('\n') } }, - '../../lib/npm.js': npm, '../../lib/utils/output.js': (...msg) => { result += msg.join('\n') }, @@ -68,10 +67,11 @@ t.afterEach(cb => { cb() }) -const profile = requireInject('../../lib/profile.js', mocks) +const Profile = requireInject('../../lib/profile.js', mocks) +const profile = new Profile(npm) t.test('no args', t => { - profile([], err => { + profile.exec([], err => { t.match( err, /usage instructions/, @@ -88,13 +88,14 @@ t.test('profile get no args', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, }) + const profile = new Profile(npm) t.test('default output', t => { - profile(['get'], err => { + profile.exec(['get'], err => { if (err) throw err @@ -109,7 +110,7 @@ t.test('profile get no args', t => { t.test('--json', t => { npm.flatOptions.json = true - profile(['get'], err => { + profile.exec(['get'], err => { if (err) throw err @@ -125,7 +126,7 @@ t.test('profile get no args', t => { t.test('--parseable', t => { npm.flatOptions.parseable = true - profile(['get'], err => { + profile.exec(['get'], err => { if (err) throw err @@ -147,12 +148,13 @@ t.test('profile get no args', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, }) + const profile = new Profile(npm) - profile(['get'], err => { + profile.exec(['get'], err => { if (err) throw err @@ -174,12 +176,13 @@ t.test('profile get no args', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, }) + const profile = new Profile(npm) - profile(['get'], err => { + profile.exec(['get'], err => { if (err) throw err @@ -201,12 +204,13 @@ t.test('profile get no args', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, }) + const profile = new Profile(npm) - profile(['get'], err => { + profile.exec(['get'], err => { if (err) throw err @@ -228,13 +232,14 @@ t.test('profile get <key>', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, }) + const profile = new Profile(npm) t.test('default output', t => { - profile(['get', 'name'], err => { + profile.exec(['get', 'name'], err => { if (err) throw err @@ -250,7 +255,7 @@ t.test('profile get <key>', t => { t.test('--json', t => { npm.flatOptions.json = true - profile(['get', 'name'], err => { + profile.exec(['get', 'name'], err => { if (err) throw err @@ -266,7 +271,7 @@ t.test('profile get <key>', t => { t.test('--parseable', t => { npm.flatOptions.parseable = true - profile(['get', 'name'], err => { + profile.exec(['get', 'name'], err => { if (err) throw err @@ -288,13 +293,14 @@ t.test('profile get multiple args', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, }) + const profile = new Profile(npm) t.test('default output', t => { - profile(['get', 'name', 'email', 'github'], err => { + profile.exec(['get', 'name', 'email', 'github'], err => { if (err) throw err @@ -309,7 +315,7 @@ t.test('profile get multiple args', t => { t.test('--json', t => { npm.flatOptions.json = true - profile(['get', 'name', 'email', 'github'], err => { + profile.exec(['get', 'name', 'email', 'github'], err => { if (err) throw err @@ -325,7 +331,7 @@ t.test('profile get multiple args', t => { t.test('--parseable', t => { npm.flatOptions.parseable = true - profile(['get', 'name', 'email', 'github'], err => { + profile.exec(['get', 'name', 'email', 'github'], err => { if (err) throw err @@ -338,7 +344,7 @@ t.test('profile get multiple args', t => { }) t.test('comma separated', t => { - profile(['get', 'name,email,github'], err => { + profile.exec(['get', 'name,email,github'], err => { if (err) throw err @@ -374,7 +380,7 @@ t.test('profile set <key> <value>', t => { }) t.test('no key', t => { - profile(['set'], err => { + profile.exec(['set'], err => { t.match( err, /npm profile set <prop> <value>/, @@ -385,7 +391,7 @@ t.test('profile set <key> <value>', t => { }) t.test('no value', t => { - profile(['set', 'email'], err => { + profile.exec(['set', 'email'], err => { t.match( err, /npm profile set <prop> <value>/, @@ -396,7 +402,7 @@ t.test('profile set <key> <value>', t => { }) t.test('set password', t => { - profile(['set', 'password', '1234'], err => { + profile.exec(['set', 'password', '1234'], err => { t.match( err, /Do not include your current or new passwords on the command line./, @@ -407,7 +413,7 @@ t.test('profile set <key> <value>', t => { }) t.test('unwritable key', t => { - profile(['set', 'name', 'foo'], err => { + profile.exec(['set', 'name', 'foo'], err => { t.match( err, /"name" is not a property we can set./, @@ -421,12 +427,13 @@ t.test('profile set <key> <value>', t => { t.test('default output', t => { t.plan(2) - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile(t), }) + const profile = new Profile(npm) - profile(['set', 'fullname', 'Lorem Ipsum'], err => { + profile.exec(['set', 'fullname', 'Lorem Ipsum'], err => { if (err) throw err @@ -443,12 +450,13 @@ t.test('profile set <key> <value>', t => { npm.flatOptions.json = true - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile(t), }) + const profile = new Profile(npm) - profile(['set', 'fullname', 'Lorem Ipsum'], err => { + profile.exec(['set', 'fullname', 'Lorem Ipsum'], err => { if (err) throw err @@ -467,12 +475,13 @@ t.test('profile set <key> <value>', t => { npm.flatOptions.parseable = true - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile(t), }) + const profile = new Profile(npm) - profile(['set', 'fullname', 'Lorem Ipsum'], err => { + profile.exec(['set', 'fullname', 'Lorem Ipsum'], err => { if (err) throw err @@ -513,12 +522,13 @@ t.test('profile set <key> <value>', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, }) + const profile = new Profile(npm) - profile(['set', 'email', 'foo@npmjs.com'], err => { + profile.exec(['set', 'email', 'foo@npmjs.com'], err => { if (err) throw err @@ -576,13 +586,14 @@ t.test('profile set <key> <value>', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, '../../lib/utils/read-user-info.js': readUserInfo, }) + const profile = new Profile(npm) - profile(['set', 'password'], err => { + profile.exec(['set', 'password'], err => { if (err) throw err @@ -643,14 +654,15 @@ t.test('profile set <key> <value>', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, npmlog, 'npm-profile': npmProfile, '../../lib/utils/read-user-info.js': readUserInfo, }) + const profile = new Profile(npm) - profile(['set', 'password'], err => { + profile.exec(['set', 'password'], err => { if (err) throw err @@ -668,7 +680,7 @@ t.test('profile set <key> <value>', t => { t.test('enable-2fa', t => { t.test('invalid args', t => { - profile(['enable-2fa', 'foo', 'bar'], err => { + profile.exec(['enable-2fa', 'foo', 'bar'], err => { t.match( err, /npm profile enable-2fa \[auth-and-writes|auth-only\]/, @@ -679,7 +691,7 @@ t.test('enable-2fa', t => { }) t.test('invalid two factor auth mode', t => { - profile(['enable-2fa', 'foo'], err => { + profile.exec(['enable-2fa', 'foo'], err => { t.match( err, /Invalid two-factor authentication mode "foo"/, @@ -692,7 +704,7 @@ t.test('enable-2fa', t => { t.test('no support for --json output', t => { npm.flatOptions.json = true - profile(['enable-2fa', 'auth-only'], err => { + profile.exec(['enable-2fa', 'auth-only'], err => { t.match( err.message, 'Enabling two-factor authentication is an interactive ' + @@ -706,7 +718,7 @@ t.test('enable-2fa', t => { t.test('no support for --parseable output', t => { npm.flatOptions.parseable = true - profile(['enable-2fa', 'auth-only'], err => { + profile.exec(['enable-2fa', 'auth-only'], err => { t.match( err.message, 'Enabling two-factor authentication is an interactive ' + @@ -733,12 +745,13 @@ t.test('enable-2fa', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, }) + const profile = new Profile(npm) - profile(['enable-2fa', 'auth-only'], err => { + profile.exec(['enable-2fa', 'auth-only'], err => { t.match( err.message, 'Your registry https://registry.npmjs.org/ does ' + @@ -761,12 +774,13 @@ t.test('enable-2fa', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, }) + const profile = new Profile(npm) - profile(['enable-2fa', 'auth-only'], err => { + profile.exec(['enable-2fa', 'auth-only'], err => { t.match( err.message, 'Your registry https://registry.npmjs.org/ does ' + @@ -781,11 +795,12 @@ t.test('enable-2fa', t => { t.test('no auth found', t => { npm.config.getCredentialsByURI = () => ({}) - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, }) + const profile = new Profile(npm) - profile(['enable-2fa', 'auth-only'], err => { + profile.exec(['enable-2fa', 'auth-only'], err => { t.match( err.message, 'You need to be logged in to registry ' + @@ -861,13 +876,14 @@ t.test('enable-2fa', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, '../../lib/utils/read-user-info.js': readUserInfo, }) + const profile = new Profile(npm) - profile(['enable-2fa', 'auth-only'], err => { + profile.exec(['enable-2fa', 'auth-only'], err => { if (err) throw err @@ -964,14 +980,15 @@ t.test('enable-2fa', t => { generate: (url, cb) => cb('qrcode'), } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, 'qrcode-terminal': qrcode, '../../lib/utils/read-user-info.js': readUserInfo, }) + const profile = new Profile(npm) - profile(['enable-2fa', 'auth-only'], err => { + profile.exec(['enable-2fa', 'auth-only'], err => { if (err) throw err @@ -1017,13 +1034,14 @@ t.test('enable-2fa', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, '../../lib/utils/read-user-info.js': readUserInfo, }) + const profile = new Profile(npm) - profile(['enable-2fa', 'auth-only'], err => { + profile.exec(['enable-2fa', 'auth-only'], err => { t.match( err, /Unknown error enabling two-factor authentication./, @@ -1063,13 +1081,14 @@ t.test('enable-2fa', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, '../../lib/utils/read-user-info.js': readUserInfo, }) + const profile = new Profile(npm) - profile(['enable-2fa', 'auth-and-writes'], err => { + profile.exec(['enable-2fa', 'auth-and-writes'], err => { if (err) throw err @@ -1113,13 +1132,14 @@ t.test('enable-2fa', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, '../../lib/utils/read-user-info.js': readUserInfo, }) + const profile = new Profile(npm) - profile(['enable-2fa', 'auth-only'], err => { + profile.exec(['enable-2fa', 'auth-only'], err => { if (err) throw err @@ -1163,13 +1183,14 @@ t.test('enable-2fa', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, '../../lib/utils/read-user-info.js': readUserInfo, }) + const profile = new Profile(npm) - profile(['enable-2fa'], err => { + profile.exec(['enable-2fa'], err => { if (err) throw err @@ -1196,12 +1217,13 @@ t.test('disable-2fa', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, }) + const profile = new Profile(npm) - profile(['disable-2fa'], err => { + profile.exec(['disable-2fa'], err => { if (err) throw err @@ -1257,13 +1279,14 @@ t.test('disable-2fa', t => { }) t.test('default output', t => { - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile(t), '../../lib/utils/read-user-info.js': readUserInfo(t), }) + const profile = new Profile(npm) - profile(['disable-2fa'], err => { + profile.exec(['disable-2fa'], err => { if (err) throw err @@ -1279,13 +1302,14 @@ t.test('disable-2fa', t => { t.test('--json', t => { npm.flatOptions.json = true - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile(t), '../../lib/utils/read-user-info.js': readUserInfo(t), }) + const profile = new Profile(npm) - profile(['disable-2fa'], err => { + profile.exec(['disable-2fa'], err => { if (err) throw err @@ -1301,13 +1325,14 @@ t.test('disable-2fa', t => { t.test('--parseable', t => { npm.flatOptions.parseable = true - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile(t), '../../lib/utils/read-user-info.js': readUserInfo(t), }) + const profile = new Profile(npm) - profile(['disable-2fa'], err => { + profile.exec(['disable-2fa'], err => { if (err) throw err @@ -1363,13 +1388,14 @@ t.test('disable-2fa', t => { }, } - const profile = requireInject('../../lib/profile.js', { + const Profile = requireInject('../../lib/profile.js', { ...mocks, 'npm-profile': npmProfile, '../../lib/utils/read-user-info.js': readUserInfo, }) + const profile = new Profile(npm) - profile(['disable-2fa'], err => { + profile.exec(['disable-2fa'], err => { if (err) throw err @@ -1385,7 +1411,7 @@ t.test('disable-2fa', t => { }) t.test('unknown subcommand', t => { - profile(['asfd'], err => { + profile.exec(['asfd'], err => { t.match( err, /Unknown profile command: asfd/, @@ -1396,11 +1422,9 @@ t.test('unknown subcommand', t => { }) t.test('completion', t => { - const { completion } = profile - const testComp = async ({ t, argv, expect, title }) => { t.resolveMatch( - completion({ conf: { argv: { remain: argv } } }), + profile.completion({ conf: { argv: { remain: argv } } }), expect, title ) @@ -1444,7 +1468,7 @@ t.test('completion', t => { t.test('npm profile unknown subcommand autocomplete', async t => { t.rejects( - completion({ conf: { argv: { remain: ['npm', 'profile', 'asdf'] } } }), + profile.completion({ conf: { argv: { remain: ['npm', 'profile', 'asdf'] } } }), { message: 'asdf not recognized' }, 'should throw unknown cmd error' ) t.end() diff --git a/deps/npm/test/lib/prune.js b/deps/npm/test/lib/prune.js index 074f4eac6e..8cd148806e 100644 --- a/deps/npm/test/lib/prune.js +++ b/deps/npm/test/lib/prune.js @@ -2,13 +2,7 @@ const { test } = require('tap') const requireInject = require('require-inject') test('should prune using Arborist', (t) => { - const prune = requireInject('../../lib/prune.js', { - '../../lib/npm.js': { - prefix: 'foo', - flatOptions: { - foo: 'bar', - }, - }, + const Prune = requireInject('../../lib/prune.js', { '@npmcli/arborist': function (args) { t.ok(args, 'gets options object') t.ok(args.path, 'gets path option') @@ -20,7 +14,13 @@ test('should prune using Arborist', (t) => { t.ok(arb, 'gets arborist tree') }, }) - prune(null, er => { + const prune = new Prune({ + prefix: 'foo', + flatOptions: { + foo: 'bar', + }, + }) + prune.exec(null, er => { if (er) throw er t.ok(true, 'callback is called') diff --git a/deps/npm/test/lib/publish.js b/deps/npm/test/lib/publish.js index 5243b52542..0e857fafdd 100644 --- a/deps/npm/test/lib/publish.js +++ b/deps/npm/test/lib/publish.js @@ -34,19 +34,7 @@ t.test('should publish with libnpmpublish, passing through flatOptions and respe }, null, 2), }) - const publish = requireInject('../../lib/publish.js', { - '../../lib/npm.js': { - flatOptions: { - customValue: true, - }, - config: { - ...config, - getCredentialsByURI: (uri) => { - t.same(uri, registry, 'gets credentials for expected registry') - return { token: 'some.registry.token' } - }, - }, - }, + const Publish = requireInject('../../lib/publish.js', { // verify that we do NOT remove publishConfig if it was there originally // and then removed during the script/pack process libnpmpack: async () => { @@ -66,11 +54,24 @@ t.test('should publish with libnpmpublish, passing through flatOptions and respe }, }, }) + const publish = new Publish({ + flatOptions: { + customValue: true, + }, + config: { + ...config, + getCredentialsByURI: (uri) => { + t.same(uri, registry, 'gets credentials for expected registry') + return { token: 'some.registry.token' } + }, + }, + }) - return publish([testDir], (er) => { + publish.exec([testDir], (er) => { if (er) throw er t.pass('got to callback') + t.end() }) }) @@ -85,16 +86,7 @@ t.test('re-loads publishConfig.registry if added during script process', (t) => }, null, 2), }) - const publish = requireInject('../../lib/publish.js', { - '../../lib/npm.js': { - config: { - ...config, - getCredentialsByURI: (uri) => { - t.same(uri, registry, 'gets credentials for expected registry') - return { token: 'some.registry.token' } - }, - }, - }, + const Publish = requireInject('../../lib/publish.js', { libnpmpack: async () => { fs.writeFileSync(`${testDir}/package.json`, JSON.stringify({ name: 'my-cool-pkg', @@ -112,11 +104,21 @@ t.test('re-loads publishConfig.registry if added during script process', (t) => }, }, }) + const publish = new Publish({ + config: { + ...config, + getCredentialsByURI: (uri) => { + t.same(uri, registry, 'gets credentials for expected registry') + return { token: 'some.registry.token' } + }, + }, + }) - return publish([testDir], (er) => { + publish.exec([testDir], (er) => { if (er) throw er t.pass('got to callback') + t.end() }) }) @@ -131,19 +133,7 @@ t.test('if loglevel=info and json, should not output package contents', (t) => { }) log.level = 'info' - const publish = requireInject('../../lib/publish.js', { - '../../lib/npm.js': { - flatOptions: { - json: true, - }, - config: { - ...config, - getCredentialsByURI: (uri) => { - t.same(uri, defaults.registry, 'gets credentials for expected registry') - return { token: 'some.registry.token' } - }, - }, - }, + const Publish = requireInject('../../lib/publish.js', { '../../lib/utils/output.js': () => { t.pass('output is called') }, @@ -161,11 +151,24 @@ t.test('if loglevel=info and json, should not output package contents', (t) => { }, }, }) + const publish = new Publish({ + flatOptions: { + json: true, + }, + config: { + ...config, + getCredentialsByURI: (uri) => { + t.same(uri, defaults.registry, 'gets credentials for expected registry') + return { token: 'some.registry.token' } + }, + }, + }) - return publish([testDir], (er) => { + publish.exec([testDir], (er) => { if (er) throw er t.pass('got to callback') + t.end() }) }) @@ -180,18 +183,7 @@ t.test('if loglevel=silent and dry-run, should not output package contents or pu }) log.level = 'silent' - const publish = requireInject('../../lib/publish.js', { - '../../lib/npm.js': { - flatOptions: { - dryRun: true, - }, - config: { - ...config, - getCredentialsByURI: () => { - throw new Error('should not call getCredentialsByURI in dry run') - }, - }, - }, + const Publish = requireInject('../../lib/publish.js', { '../../lib/utils/output.js': () => { throw new Error('should not output in dry run mode') }, @@ -209,11 +201,23 @@ t.test('if loglevel=silent and dry-run, should not output package contents or pu }, }, }) + const publish = new Publish({ + flatOptions: { + dryRun: true, + }, + config: { + ...config, + getCredentialsByURI: () => { + throw new Error('should not call getCredentialsByURI in dry run') + }, + }, + }) - return publish([testDir], (er) => { + publish.exec([testDir], (er) => { if (er) throw er t.pass('got to callback') + t.end() }) }) @@ -228,17 +232,7 @@ t.test('if loglevel=info and dry-run, should not publish, should log package con }) log.level = 'info' - const publish = requireInject('../../lib/publish.js', { - '../../lib/npm.js': { - flatOptions: { - dryRun: true, - }, - config: { - ...config, - getCredentialsByURI: () => { - throw new Error('should not call getCredentialsByURI in dry run') - }}, - }, + const Publish = requireInject('../../lib/publish.js', { '../../lib/utils/tar.js': { getContents: () => ({ id: 'someid', @@ -256,37 +250,52 @@ t.test('if loglevel=info and dry-run, should not publish, should log package con }, }, }) + const publish = new Publish({ + flatOptions: { + dryRun: true, + }, + config: { + ...config, + getCredentialsByURI: () => { + throw new Error('should not call getCredentialsByURI in dry run') + }}, + }) - return publish([testDir], (er) => { + publish.exec([testDir], (er) => { if (er) throw er t.pass('got to callback') + t.end() }) }) t.test('shows usage with wrong set of arguments', (t) => { t.plan(1) - const publish = requireInject('../../lib/publish.js') + const Publish = requireInject('../../lib/publish.js') + const publish = new Publish({}) - return publish(['a', 'b', 'c'], (er) => t.matchSnapshot(er, 'should print usage')) + publish.exec(['a', 'b', 'c'], (er) => { + t.matchSnapshot(er, 'should print usage') + t.end() + }) }) t.test('throws when invalid tag', (t) => { t.plan(1) - const publish = requireInject('../../lib/publish.js', { - '../../lib/npm.js': { - flatOptions: { - defaultTag: '0.0.13', - }, - config, + const Publish = requireInject('../../lib/publish.js') + const publish = new Publish({ + flatOptions: { + defaultTag: '0.0.13', }, + config, }) - return publish([], (err) => { + publish.exec([], (err) => { t.match(err, { message: /Tag name must not be a valid SemVer range: /, }, 'throws when tag name is a valid SemVer range') + t.end() }) }) @@ -310,16 +319,7 @@ t.test('can publish a tarball', t => { }, ['package']) const tarFile = fs.readFileSync(`${testDir}/tarball/package.tgz`) - const publish = requireInject('../../lib/publish.js', { - '../../lib/npm.js': { - config: { - ...config, - getCredentialsByURI: (uri) => { - t.same(uri, defaults.registry, 'gets credentials for expected registry') - return { token: 'some.registry.token' } - }, - }, - }, + const Publish = requireInject('../../lib/publish.js', { libnpmpublish: { publish: (manifest, tarData, opts) => { t.match(manifest, { @@ -330,63 +330,73 @@ t.test('can publish a tarball', t => { }, }, }) + const publish = new Publish({ + config: { + ...config, + getCredentialsByURI: (uri) => { + t.same(uri, defaults.registry, 'gets credentials for expected registry') + return { token: 'some.registry.token' } + }, + }, + }) - return publish([`${testDir}/tarball/package.tgz`], (er) => { + publish.exec([`${testDir}/tarball/package.tgz`], (er) => { if (er) throw er t.pass('got to callback') + t.end() }) }) -t.test('should check auth for default registry', async t => { +t.test('should check auth for default registry', t => { t.plan(2) - const publish = requireInject('../../lib/publish.js', { - '../../lib/npm.js': { - config: { - ...config, - getCredentialsByURI: (uri) => { - t.same(uri, defaults.registry, 'gets credentials for expected registry') - return {} - }, + const Publish = requireInject('../../lib/publish.js') + const publish = new Publish({ + config: { + ...config, + getCredentialsByURI: (uri) => { + t.same(uri, defaults.registry, 'gets credentials for expected registry') + return {} }, }, }) - return publish([], (err) => { + publish.exec([], (err) => { t.match(err, { message: 'This command requires you to be logged in.', code: 'ENEEDAUTH', }, 'throws when not logged in') + t.end() }) }) -t.test('should check auth for configured registry', async t => { +t.test('should check auth for configured registry', t => { t.plan(2) const registry = 'https://some.registry' - const publish = requireInject('../../lib/publish.js', { - '../../lib/npm.js': { - flatOptions: { - registry, - }, - config: { - ...config, - getCredentialsByURI: (uri) => { - t.same(uri, registry, 'gets credentials for expected registry') - return {} - }, + const Publish = requireInject('../../lib/publish.js') + const publish = new Publish({ + flatOptions: { + registry, + }, + config: { + ...config, + getCredentialsByURI: (uri) => { + t.same(uri, registry, 'gets credentials for expected registry') + return {} }, }, }) - return publish([], (err) => { + publish.exec([], (err) => { t.match(err, { message: 'This command requires you to be logged in.', code: 'ENEEDAUTH', }, 'throws when not logged in') + t.end() }) }) -t.test('should check auth for scope specific registry', async t => { +t.test('should check auth for scope specific registry', t => { t.plan(2) const registry = 'https://some.registry' const testDir = t.testdir({ @@ -396,26 +406,26 @@ t.test('should check auth for scope specific registry', async t => { }, null, 2), }) - const publish = requireInject('../../lib/publish.js', { - '../../lib/npm.js': { - flatOptions: { - '@npm:registry': registry, - }, - config: { - ...config, - getCredentialsByURI: (uri) => { - t.same(uri, registry, 'gets credentials for expected registry') - return {} - }, + const Publish = requireInject('../../lib/publish.js') + const publish = new Publish({ + flatOptions: { + '@npm:registry': registry, + }, + config: { + ...config, + getCredentialsByURI: (uri) => { + t.same(uri, registry, 'gets credentials for expected registry') + return {} }, }, }) - return publish([testDir], (err) => { + publish.exec([testDir], (err) => { t.match(err, { message: 'This command requires you to be logged in.', code: 'ENEEDAUTH', }, 'throws when not logged in') + t.end() }) }) @@ -429,19 +439,7 @@ t.test('should use auth for scope specific registry', t => { }, null, 2), }) - const publish = requireInject('../../lib/publish.js', { - '../../lib/npm.js': { - flatOptions: { - '@npm:registry': registry, - }, - config: { - ...config, - getCredentialsByURI: (uri) => { - t.same(uri, registry, 'gets credentials for expected registry') - return { token: 'some.registry.token' } - }, - }, - }, + const Publish = requireInject('../../lib/publish.js', { libnpmpublish: { publish: (manifest, tarData, opts) => { t.ok(opts, 'gets opts object') @@ -449,10 +447,23 @@ t.test('should use auth for scope specific registry', t => { }, }, }) - return publish([testDir], (er) => { + const publish = new Publish({ + flatOptions: { + '@npm:registry': registry, + }, + config: { + ...config, + getCredentialsByURI: (uri) => { + t.same(uri, registry, 'gets credentials for expected registry') + return { token: 'some.registry.token' } + }, + }, + }) + publish.exec([testDir], (er) => { if (er) throw er t.pass('got to callback') + t.end() }) }) @@ -469,16 +480,7 @@ t.test('read registry only from publishConfig', t => { }, null, 2), }) - const publish = requireInject('../../lib/publish.js', { - '../../lib/npm.js': { - config: { - ...config, - getCredentialsByURI: (uri) => { - t.same(uri, registry, 'gets credentials for expected registry') - return { token: 'some.registry.token' } - }, - }, - }, + const Publish = requireInject('../../lib/publish.js', { libnpmpublish: { publish: (manifest, tarData, opts) => { t.match(manifest, { name: 'my-cool-pkg', version: '1.0.0' }, 'gets manifest') @@ -486,10 +488,20 @@ t.test('read registry only from publishConfig', t => { }, }, }) + const publish = new Publish({ + config: { + ...config, + getCredentialsByURI: (uri) => { + t.same(uri, registry, 'gets credentials for expected registry') + return { token: 'some.registry.token' } + }, + }, + }) - return publish([testDir], (er) => { + publish.exec([testDir], (er) => { if (er) throw er t.pass('got to callback') + t.end() }) }) diff --git a/deps/npm/test/lib/rebuild.js b/deps/npm/test/lib/rebuild.js index d9df048d90..ee081c087f 100644 --- a/deps/npm/test/lib/rebuild.js +++ b/deps/npm/test/lib/rebuild.js @@ -13,14 +13,14 @@ const npm = { prefix: '', } const mocks = { - '../../lib/npm.js': npm, '../../lib/utils/output.js': (...msg) => { result += msg.join('\n') }, '../../lib/utils/usage.js': () => 'usage instructions', } -const rebuild = requireInject('../../lib/rebuild.js', mocks) +const Rebuild = requireInject('../../lib/rebuild.js', mocks) +const rebuild = new Rebuild(npm) t.afterEach(cb => { npm.prefix = '' @@ -67,7 +67,7 @@ t.test('no args', t => { npm.prefix = path - rebuild([], err => { + rebuild.exec([], err => { if (err) throw err @@ -115,7 +115,7 @@ t.test('filter by pkg name', t => { t.throws(() => fs.statSync(aBinFile)) t.throws(() => fs.statSync(bBinFile)) - rebuild(['b'], err => { + rebuild.exec(['b'], err => { if (err) throw err @@ -163,7 +163,7 @@ t.test('filter by pkg@<range>', t => { const bBinFile = resolve(path, 'node_modules/.bin/b') const nestedBinFile = resolve(path, 'node_modules/a/node_modules/.bin/b') - rebuild(['b@2'], err => { + rebuild.exec(['b@2'], err => { if (err) throw err @@ -203,7 +203,7 @@ t.test('filter by directory', t => { t.throws(() => fs.statSync(aBinFile)) t.throws(() => fs.statSync(bBinFile)) - rebuild(['file:node_modules/b'], err => { + rebuild.exec(['file:node_modules/b'], err => { if (err) throw err @@ -215,7 +215,7 @@ t.test('filter by directory', t => { }) t.test('filter must be a semver version/range, or directory', t => { - rebuild(['git+ssh://github.com/npm/arborist'], err => { + rebuild.exec(['git+ssh://github.com/npm/arborist'], err => { t.match( err, /Error: `npm rebuild` only supports SemVer version\/range specifiers/, @@ -245,7 +245,7 @@ t.test('global prefix', t => { npm.flatOptions.global = true npm.globalDir = resolve(globalPath, 'lib', 'node_modules') - rebuild([], err => { + rebuild.exec([], err => { if (err) throw err diff --git a/deps/npm/test/lib/repo.js b/deps/npm/test/lib/repo.js index 3367f7c885..9c22bbaea3 100644 --- a/deps/npm/test/lib/repo.js +++ b/deps/npm/test/lib/repo.js @@ -108,16 +108,16 @@ const pacote = { // keep a tally of which urls got opened const opened = {} -const openUrl = (url, errMsg, cb) => { +const openUrl = async (npm, url, errMsg) => { opened[url] = opened[url] || 0 opened[url]++ - process.nextTick(cb) } -const repo = requireInject('../../lib/repo.js', { +const Repo = requireInject('../../lib/repo.js', { pacote, '../../lib/utils/open-url.js': openUrl, }) +const repo = new Repo({ flatOptions: {} }) t.test('open repo urls', t => { const expect = { @@ -150,7 +150,7 @@ t.test('open repo urls', t => { t.plan(keys.length) keys.forEach(pkg => { t.test(pkg, t => { - repo([pkg], (er) => { + repo.exec([pkg], (er) => { if (er) throw er const url = expect[pkg] @@ -173,7 +173,7 @@ t.test('fail if cannot figure out repo url', t => { cases.forEach(pkg => { t.test(pkg, t => { - repo([pkg], er => { + repo.exec([pkg], er => { t.match(er, { pkgid: pkg }) t.end() }) @@ -182,7 +182,7 @@ t.test('fail if cannot figure out repo url', t => { }) t.test('open default package if none specified', t => { - repo([], (er) => { + repo.exec([], (er) => { if (er) throw er t.equal(opened['https://example.com/thispkg'], 2, 'opened expected url', {opened}) diff --git a/deps/npm/test/lib/restart.js b/deps/npm/test/lib/restart.js index a19bfd0d41..f29592d9bf 100644 --- a/deps/npm/test/lib/restart.js +++ b/deps/npm/test/lib/restart.js @@ -1,4 +1,17 @@ const t = require('tap') -const restart = require('../../lib/restart.js') -t.isa(restart, Function) +let runArgs +const npm = { + commands: { + 'run-script': (args, cb) => { + runArgs = args + cb() + }, + }, +} +const Restart = require('../../lib/restart.js') +const restart = new Restart(npm) t.equal(restart.usage, 'npm restart [-- <args>]') +restart.exec(['foo'], () => { + t.match(runArgs, ['restart', 'foo']) + t.end() +}) diff --git a/deps/npm/test/lib/root.js b/deps/npm/test/lib/root.js index 8c23152b3e..e8ccc1106d 100644 --- a/deps/npm/test/lib/root.js +++ b/deps/npm/test/lib/root.js @@ -5,14 +5,14 @@ test('root', (t) => { t.plan(3) const dir = '/root/dir' - const root = requireInject('../../lib/root.js', { - '../../lib/npm.js': { dir }, + const Root = requireInject('../../lib/root.js', { '../../lib/utils/output.js': (output) => { t.equal(output, dir, 'prints the correct directory') }, }) + const root = new Root({ dir }) - root([], (err) => { + root.exec([], (err) => { t.ifError(err, 'npm root') t.ok('should have printed directory') }) diff --git a/deps/npm/test/lib/run-script.js b/deps/npm/test/lib/run-script.js index 974202aa8c..43592d3243 100644 --- a/deps/npm/test/lib/run-script.js +++ b/deps/npm/test/lib/run-script.js @@ -22,19 +22,29 @@ const npm = { const output = [] -const npmlog = { level: 'warn' } -const getRS = windows => requireInject('../../lib/run-script.js', { - '@npmcli/run-script': Object.assign(async opts => { - RUN_SCRIPTS.push(opts) - }, { - isServerPackage: require('@npmcli/run-script').isServerPackage, - }), - npmlog, - '../../lib/npm.js': npm, - '../../lib/utils/is-windows-shell.js': windows, - '../../lib/utils/output.js': (...msg) => output.push(msg), +t.afterEach(cb => { + output.length = 0 + RUN_SCRIPTS.length = 0 + npm.flatOptions.json = false + npm.flatOptions.parseable = false + cb() }) +const npmlog = { level: 'warn' } +const getRS = windows => { + const RunScript = requireInject('../../lib/run-script.js', { + '@npmcli/run-script': Object.assign(async opts => { + RUN_SCRIPTS.push(opts) + }, { + isServerPackage: require('@npmcli/run-script').isServerPackage, + }), + npmlog, + '../../lib/utils/is-windows-shell.js': windows, + '../../lib/utils/output.js': (...msg) => output.push(msg), + }) + return new RunScript(npm) +} + const runScript = getRS(false) const runScriptWin = getRS(true) @@ -69,109 +79,119 @@ t.test('completion', t => { t.end() }) -t.test('fail if no package.json', async t => { +t.test('fail if no package.json', t => { + t.plan(2) npm.localPrefix = t.testdir() - await runScript([], er => t.match(er, { code: 'ENOENT' })) - await runScript(['test'], er => t.match(er, { code: 'ENOENT' })) + runScript.exec([], er => t.match(er, { code: 'ENOENT' })) + runScript.exec(['test'], er => t.match(er, { code: 'ENOENT' })) }) -t.test('default env, start, and restart scripts', async t => { +t.test('default env, start, and restart scripts', t => { npm.localPrefix = t.testdir({ 'package.json': JSON.stringify({ name: 'x', version: '1.2.3' }), 'server.js': 'console.log("hello, world")', }) - await runScript(['start'], er => { - if (er) - throw er + t.test('start', t => { + runScript.exec(['start'], er => { + if (er) + throw er - t.match(RUN_SCRIPTS, [ - { - path: npm.localPrefix, - args: [], - scriptShell: undefined, - stdio: 'inherit', - stdioString: true, - pkg: { name: 'x', version: '1.2.3', _id: 'x@1.2.3', scripts: {}}, - event: 'start', - }, - ]) + t.match(RUN_SCRIPTS, [ + { + path: npm.localPrefix, + args: [], + scriptShell: undefined, + stdio: 'inherit', + stdioString: true, + pkg: { name: 'x', version: '1.2.3', _id: 'x@1.2.3', scripts: {}}, + event: 'start', + }, + ]) + t.end() + }) }) - RUN_SCRIPTS.length = 0 - await runScript(['env'], er => { - if (er) - throw er + t.test('env', t => { + runScript.exec(['env'], er => { + if (er) + throw er - t.match(RUN_SCRIPTS, [ - { - path: npm.localPrefix, - args: [], - scriptShell: undefined, - stdio: 'inherit', - stdioString: true, - pkg: { - name: 'x', - version: '1.2.3', - _id: 'x@1.2.3', - scripts: { - env: 'env', + t.match(RUN_SCRIPTS, [ + { + path: npm.localPrefix, + args: [], + scriptShell: undefined, + stdio: 'inherit', + stdioString: true, + pkg: { + name: 'x', + version: '1.2.3', + _id: 'x@1.2.3', + scripts: { + env: 'env', + }, }, + event: 'env', }, - event: 'env', - }, - ]) + ]) + t.end() + }) }) - RUN_SCRIPTS.length = 0 - await runScriptWin(['env'], er => { - if (er) - throw er + t.test('windows env', t => { + runScriptWin.exec(['env'], er => { + if (er) + throw er - t.match(RUN_SCRIPTS, [ - { - path: npm.localPrefix, - args: [], - scriptShell: undefined, - stdio: 'inherit', - stdioString: true, - pkg: { name: 'x', - version: '1.2.3', - _id: 'x@1.2.3', - scripts: { - env: 'SET', - } }, - event: 'env', - }, - ]) + t.match(RUN_SCRIPTS, [ + { + path: npm.localPrefix, + args: [], + scriptShell: undefined, + stdio: 'inherit', + stdioString: true, + pkg: { name: 'x', + version: '1.2.3', + _id: 'x@1.2.3', + scripts: { + env: 'SET', + } }, + event: 'env', + }, + ]) + t.end() + }) }) - RUN_SCRIPTS.length = 0 - await runScript(['restart'], er => { - if (er) - throw er + t.test('restart', t => { + runScript.exec(['restart'], er => { + if (er) + throw er - t.match(RUN_SCRIPTS, [ - { - path: npm.localPrefix, - args: [], - scriptShell: undefined, - stdio: 'inherit', - stdioString: true, - pkg: { name: 'x', - version: '1.2.3', - _id: 'x@1.2.3', - scripts: { - restart: 'npm stop --if-present && npm start', - } }, - event: 'restart', - }, - ]) + t.match(RUN_SCRIPTS, [ + { + path: npm.localPrefix, + args: [], + scriptShell: undefined, + stdio: 'inherit', + stdioString: true, + pkg: { name: 'x', + version: '1.2.3', + _id: 'x@1.2.3', + scripts: { + restart: 'npm stop --if-present && npm start', + } }, + event: 'restart', + }, + ]) + t.end() + }) }) - RUN_SCRIPTS.length = 0 + t.end() }) -t.test('non-default env script', async t => { +t.test('non-default env script', t => { npm.localPrefix = t.testdir({ 'package.json': JSON.stringify({ name: 'x', @@ -182,54 +202,59 @@ t.test('non-default env script', async t => { }), }) - await runScript(['env'], er => { - if (er) - throw er + t.test('env', t => { + runScript.exec(['env'], er => { + if (er) + throw er - t.match(RUN_SCRIPTS, [ - { - path: npm.localPrefix, - args: [], - scriptShell: undefined, - stdio: 'inherit', - stdioString: true, - pkg: { - name: 'x', - version: '1.2.3', - _id: 'x@1.2.3', - scripts: { - env: 'hello', + t.match(RUN_SCRIPTS, [ + { + path: npm.localPrefix, + args: [], + scriptShell: undefined, + stdio: 'inherit', + stdioString: true, + pkg: { + name: 'x', + version: '1.2.3', + _id: 'x@1.2.3', + scripts: { + env: 'hello', + }, }, + event: 'env', }, - event: 'env', - }, - ]) + ]) + t.end() + }) }) - RUN_SCRIPTS.length = 0 - await runScriptWin(['env'], er => { - if (er) - throw er + t.test('env windows', t => { + runScriptWin.exec(['env'], er => { + if (er) + throw er - t.match(RUN_SCRIPTS, [ - { - path: npm.localPrefix, - args: [], - scriptShell: undefined, - stdio: 'inherit', - stdioString: true, - pkg: { name: 'x', - version: '1.2.3', - _id: 'x@1.2.3', - scripts: { - env: 'hello', + t.match(RUN_SCRIPTS, [ + { + path: npm.localPrefix, + args: [], + scriptShell: undefined, + stdio: 'inherit', + stdioString: true, + pkg: { name: 'x', + version: '1.2.3', + _id: 'x@1.2.3', + scripts: { + env: 'hello', + }, }, + event: 'env', }, - event: 'env', - }, - ]) + ]) + t.end() + }) }) - RUN_SCRIPTS.length = 0 + t.end() }) t.test('try to run missing script', t => { @@ -238,33 +263,36 @@ t.test('try to run missing script', t => { scripts: { hello: 'world' }, }), }) - t.test('no suggestions', async t => { - await runScript(['notevenclose'], er => { + t.test('no suggestions', t => { + runScript.exec(['notevenclose'], er => { t.match(er, { message: 'missing script: notevenclose', }) + t.end() }) }) - t.test('suggestions', async t => { - await runScript(['helo'], er => { + t.test('suggestions', t => { + runScript.exec(['helo'], er => { t.match(er, { message: 'missing script: helo\n\nDid you mean this?\n hello', }) + t.end() }) }) - t.test('with --if-present', async t => { + t.test('with --if-present', t => { npm.config.set('if-present', true) - await runScript(['goodbye'], er => { + runScript.exec(['goodbye'], er => { if (er) throw er t.strictSame(RUN_SCRIPTS, [], 'did not try to run anything') + t.end() }) }) t.end() }) -t.test('run pre/post hooks', async t => { +t.test('run pre/post hooks', t => { npm.localPrefix = t.testdir({ 'package.json': JSON.stringify({ name: 'x', @@ -276,7 +304,7 @@ t.test('run pre/post hooks', async t => { }), }) - await runScript(['env'], er => { + runScript.exec(['env'], er => { if (er) throw er @@ -298,11 +326,11 @@ t.test('run pre/post hooks', async t => { }, { event: 'postenv' }, ]) + t.end() }) - RUN_SCRIPTS.length = 0 }) -t.test('skip pre/post hooks when using ignoreScripts', async t => { +t.test('skip pre/post hooks when using ignoreScripts', t => { npm.flatOptions.ignoreScripts = true npm.localPrefix = t.testdir({ @@ -316,7 +344,7 @@ t.test('skip pre/post hooks when using ignoreScripts', async t => { }), }) - await runScript(['env'], er => { + runScript.exec(['env'], er => { if (er) throw er @@ -339,13 +367,12 @@ t.test('skip pre/post hooks when using ignoreScripts', async t => { event: 'env', }, ]) - + t.end() delete npm.flatOptions.ignoreScripts }) - RUN_SCRIPTS.length = 0 }) -t.test('run silent', async t => { +t.test('run silent', t => { npmlog.level = 'silent' t.teardown(() => { npmlog.level = 'warn' @@ -362,7 +389,7 @@ t.test('run silent', async t => { }), }) - await runScript(['env'], er => { + runScript.exec(['env'], er => { if (er) throw er @@ -391,11 +418,11 @@ t.test('run silent', async t => { stdio: 'inherit', }, ]) + t.end() }) - RUN_SCRIPTS.length = 0 }) -t.test('list scripts', async t => { +t.test('list scripts', t => { const scripts = { test: 'exit 2', start: 'node server.js', @@ -411,55 +438,62 @@ t.test('list scripts', async t => { }), }) - await runScript([], er => { - if (er) - throw er + t.test('no args', t => { + runScript.exec([], er => { + if (er) + throw er + t.strictSame(output, [ + ['Lifecycle scripts included in x:'], + [' test\n exit 2'], + [' start\n node server.js'], + [' stop\n node kill-server.js'], + ['\navailable via `npm run-script`:'], + [' preenv\n echo before the env'], + [' postenv\n echo after the env'], + ], 'basic report') + t.end() + }) }) - t.strictSame(output, [ - ['Lifecycle scripts included in x:'], - [' test\n exit 2'], - [' start\n node server.js'], - [' stop\n node kill-server.js'], - ['\navailable via `npm run-script`:'], - [' preenv\n echo before the env'], - [' postenv\n echo after the env'], - ], 'basic report') - output.length = 0 - npmlog.level = 'silent' - await runScript([], er => { - if (er) - throw er + t.test('silent', t => { + npmlog.level = 'silent' + runScript.exec([], er => { + if (er) + throw er + t.strictSame(output, []) + t.end() + }) }) - t.strictSame(output, []) - npmlog.level = 'warn' - - npm.flatOptions.json = true - await runScript([], er => { - if (er) - throw er + t.test('warn json', t => { + npmlog.level = 'warn' + npm.flatOptions.json = true + runScript.exec([], er => { + if (er) + throw er + t.strictSame(output, [[JSON.stringify(scripts, 0, 2)]], 'json report') + t.end() + }) }) - t.strictSame(output, [[JSON.stringify(scripts, 0, 2)]], 'json report') - output.length = 0 - npm.flatOptions.json = false - npm.flatOptions.parseable = true - await runScript([], er => { - if (er) - throw er + t.test('parseable', t => { + npm.flatOptions.parseable = true + runScript.exec([], er => { + if (er) + throw er + t.strictSame(output, [ + ['test:exit 2'], + ['start:node server.js'], + ['stop:node kill-server.js'], + ['preenv:echo before the env'], + ['postenv:echo after the env'], + ]) + t.end() + }) }) - t.strictSame(output, [ - ['test:exit 2'], - ['start:node server.js'], - ['stop:node kill-server.js'], - ['preenv:echo before the env'], - ['postenv:echo after the env'], - ]) - output.length = 0 - npm.flatOptions.parseable = false + t.end() }) -t.test('list scripts when no scripts', async t => { +t.test('list scripts when no scripts', t => { npm.localPrefix = t.testdir({ 'package.json': JSON.stringify({ name: 'x', @@ -467,15 +501,15 @@ t.test('list scripts when no scripts', async t => { }), }) - await runScript([], er => { + runScript.exec([], er => { if (er) throw er + t.strictSame(output, [], 'nothing to report') + t.end() }) - t.strictSame(output, [], 'nothing to report') - output.length = 0 }) -t.test('list scripts, only commands', async t => { +t.test('list scripts, only commands', t => { npm.localPrefix = t.testdir({ 'package.json': JSON.stringify({ name: 'x', @@ -484,18 +518,18 @@ t.test('list scripts, only commands', async t => { }), }) - await runScript([], er => { + runScript.exec([], er => { if (er) throw er + t.strictSame(output, [ + ['Lifecycle scripts included in x:'], + [' preversion\n echo doing the version dance'], + ]) + t.end() }) - t.strictSame(output, [ - ['Lifecycle scripts included in x:'], - [' preversion\n echo doing the version dance'], - ]) - output.length = 0 }) -t.test('list scripts, only non-commands', async t => { +t.test('list scripts, only non-commands', t => { npm.localPrefix = t.testdir({ 'package.json': JSON.stringify({ name: 'x', @@ -504,13 +538,13 @@ t.test('list scripts, only non-commands', async t => { }), }) - await runScript([], er => { + runScript.exec([], er => { if (er) throw er + t.strictSame(output, [ + ['Scripts available in x via `npm run-script`:'], + [' glorp\n echo doing the glerp glop'], + ]) + t.end() }) - t.strictSame(output, [ - ['Scripts available in x via `npm run-script`:'], - [' glorp\n echo doing the glerp glop'], - ]) - output.length = 0 }) diff --git a/deps/npm/test/lib/search.js b/deps/npm/test/lib/search.js index 1dba1250e0..59c59f3b96 100644 --- a/deps/npm/test/lib/search.js +++ b/deps/npm/test/lib/search.js @@ -23,7 +23,6 @@ const libnpmsearch = { const mocks = { npmlog, libnpmsearch, - '../../lib/npm.js': npm, '../../lib/utils/output.js': (...msg) => { result += msg.join('\n') }, @@ -37,10 +36,11 @@ t.afterEach(cb => { cb() }) -const search = requireInject('../../lib/search.js', mocks) +const Search = requireInject('../../lib/search.js', mocks) +const search = new Search(npm) t.test('no args', t => { - search([], err => { + search.exec([], err => { t.match( err, /search must be called with arguments/, @@ -59,12 +59,13 @@ t.test('search <name>', t => { }, } - const search = requireInject('../../lib/search.js', { + const Search = requireInject('../../lib/search.js', { ...mocks, libnpmsearch, }) + const search = new Search(npm) - search(['libnpm'], err => { + search.exec(['libnpm'], err => { if (err) throw err @@ -93,12 +94,13 @@ t.test('search <name> --searchexclude --searchopts', t => { }, } - const search = requireInject('../../lib/search.js', { + const Search = requireInject('../../lib/search.js', { ...mocks, libnpmsearch, }) + const search = new Search(npm) - search(['foo'], err => { + search.exec(['foo'], err => { if (err) throw err @@ -146,12 +148,13 @@ t.test('empty search results', t => { }, } - const search = requireInject('../../lib/search.js', { + const Search = requireInject('../../lib/search.js', { ...mocks, libnpmsearch, }) + const search = new Search(npm) - search(['foo'], err => { + search.exec(['foo'], err => { if (err) throw err @@ -172,12 +175,13 @@ t.test('search api response error', t => { }, } - const search = requireInject('../../lib/search.js', { + const Search = requireInject('../../lib/search.js', { ...mocks, libnpmsearch, }) + const search = new Search(npm) - search(['foo'], err => { + search.exec(['foo'], err => { t.match( err, /ERR/, diff --git a/deps/npm/test/lib/set-script.js b/deps/npm/test/lib/set-script.js index 196fd3d3e6..7a057c5036 100644 --- a/deps/npm/test/lib/set-script.js +++ b/deps/npm/test/lib/set-script.js @@ -1,54 +1,50 @@ const test = require('tap') const requireInject = require('require-inject') -const setScriptDefault = require('../../lib/set-script.js') const parseJSON = require('json-parse-even-better-errors') -test.type(setScriptDefault, 'function', 'command is function') -test.equal(setScriptDefault.usage, 'npm set-script [<script>] [<command>]', 'usage matches') test.test('fails on invalid arguments', (t) => { - const setScript = requireInject('../../lib/set-script.js', { - fs: {}, + const SetScript = requireInject('../../lib/set-script.js', { npmlog: {}, }) + const setScript = new SetScript({}) t.plan(3) - setScript(['arg1'], (fail) => t.match(fail, /Expected 2 arguments: got 1/)) - setScript(['arg1', 'arg2', 'arg3'], (fail) => t.match(fail, /Expected 2 arguments: got 3/)) - setScript(['arg1', 'arg2', 'arg3', 'arg4'], (fail) => t.match(fail, /Expected 2 arguments: got 4/)) + setScript.exec(['arg1'], (fail) => t.match(fail, /Expected 2 arguments: got 1/)) + setScript.exec(['arg1', 'arg2', 'arg3'], (fail) => t.match(fail, /Expected 2 arguments: got 3/)) + setScript.exec(['arg1', 'arg2', 'arg3', 'arg4'], (fail) => t.match(fail, /Expected 2 arguments: got 4/)) }) test.test('fails if run in postinstall script', (t) => { - var originalVar = process.env.npm_lifecycle_event + const originalVar = process.env.npm_lifecycle_event process.env.npm_lifecycle_event = 'postinstall' - const setScript = requireInject('../../lib/set-script.js', { - fs: {}, + const SetScript = requireInject('../../lib/set-script.js', { npmlog: {}, }) t.plan(1) - setScript(['arg1', 'arg2'], (fail) => t.equal(fail.toString(), 'Error: Scripts can’t set from the postinstall script')) + const setScript = new SetScript({}) + setScript.exec(['arg1', 'arg2'], (fail) => t.equal(fail.toString(), 'Error: Scripts can’t set from the postinstall script')) process.env.npm_lifecycle_event = originalVar }) test.test('fails when package.json not found', (t) => { - const setScript = requireInject('../../lib/set-script.js', { - '../../lib/npm.js': { - localPrefix: 'IDONTEXIST', - }, - }) + const SetScript = requireInject('../../lib/set-script.js') + const setScript = new SetScript({}) t.plan(1) - setScript(['arg1', 'arg2'], (fail) => t.match(fail, /package.json not found/)) + setScript.exec(['arg1', 'arg2'], (fail) => t.match(fail, /package.json not found/)) }) test.test('fails on invalid JSON', (t) => { - const setScript = requireInject('../../lib/set-script.js', { + const SetScript = requireInject('../../lib/set-script.js', { fs: { + readFile: () => {}, // read-package-json-fast explodes w/o this readFileSync: (name, charcode) => { return 'iamnotjson' }, }, }) + const setScript = new SetScript({}) t.plan(1) - setScript(['arg1', 'arg2'], (fail) => t.match(fail, /Invalid package.json: JSONParseError/)) + setScript.exec(['arg1', 'arg2'], (fail) => t.match(fail, /Invalid package.json: JSONParseError/)) }) test.test('creates scripts object', (t) => { var mockFile = '' - const setScript = requireInject('../../lib/set-script.js', { + const SetScript = requireInject('../../lib/set-script.js', { fs: { readFileSync: (name, charcode) => { return '{}' @@ -64,15 +60,16 @@ test.test('creates scripts object', (t) => { } }, }) + const setScript = new SetScript({}) t.plan(2) - setScript(['arg1', 'arg2'], (error) => { + setScript.exec(['arg1', 'arg2'], (error) => { t.equal(error, undefined) t.assert(parseJSON(mockFile), {scripts: {arg1: 'arg2'}}) }) }) test.test('warns before overwriting', (t) => { var warningListened = '' - const setScript = requireInject('../../lib/set-script.js', { + const SetScript = requireInject('../../lib/set-script.js', { fs: { readFileSync: (name, charcode) => { return JSON.stringify({ @@ -95,15 +92,16 @@ test.test('warns before overwriting', (t) => { }, }, }) + const setScript = new SetScript({}) t.plan(2) - setScript(['arg1', 'arg2'], (error) => { + setScript.exec(['arg1', 'arg2'], (error) => { t.equal(error, undefined, 'no error') t.equal(warningListened, 'Script "arg1" was overwritten') }) }) test.test('provided indentation and eol is used', (t) => { var mockFile = '' - const setScript = requireInject('../../lib/set-script.js', { + const SetScript = requireInject('../../lib/set-script.js', { fs: { readFileSync: (name, charcode) => { return '{}' @@ -119,8 +117,9 @@ test.test('provided indentation and eol is used', (t) => { } }, }) + const setScript = new SetScript({}) t.plan(3) - setScript(['arg1', 'arg2'], (error) => { + setScript.exec(['arg1', 'arg2'], (error) => { t.equal(error, undefined) t.equal(mockFile.split('\r\n').length > 1, true) t.equal(mockFile.split('\r\n').every((value) => !value.startsWith(' ') || value.startsWith(' '.repeat(6))), true) @@ -128,7 +127,7 @@ test.test('provided indentation and eol is used', (t) => { }) test.test('goes to default when undefined indent and eol provided', (t) => { var mockFile = '' - const setScript = requireInject('../../lib/set-script.js', { + const SetScript = requireInject('../../lib/set-script.js', { fs: { readFileSync: (name, charcode) => { return '{}' @@ -144,8 +143,9 @@ test.test('goes to default when undefined indent and eol provided', (t) => { } }, }) + const setScript = new SetScript({}) t.plan(3) - setScript(['arg1', 'arg2'], (error) => { + setScript.exec(['arg1', 'arg2'], (error) => { t.equal(error, undefined) t.equal(mockFile.split('\n').length > 1, true) t.equal(mockFile.split('\n').every((value) => !value.startsWith(' ') || value.startsWith(' ')), true) diff --git a/deps/npm/test/lib/set.js b/deps/npm/test/lib/set.js index aeb239e9c4..3b38fdc276 100644 --- a/deps/npm/test/lib/set.js +++ b/deps/npm/test/lib/set.js @@ -1,4 +1,4 @@ -const { test } = require('tap') +const t = require('tap') const requireInject = require('require-inject') let configArgs = null @@ -6,24 +6,23 @@ const npm = { commands: { config: (args, cb) => { configArgs = args - return cb() + cb() }, }, } -const set = requireInject('../../lib/set.js', { - '../../lib/npm.js': npm, -}) +const Set = requireInject('../../lib/set.js') +const set = new Set(npm) -test('npm set - no args', t => { - return set([], (err) => { +t.test('npm set - no args', t => { + set.exec([], (err) => { t.match(err, /npm set/, 'prints usage') t.end() }) }) -test('npm set', t => { - return set(['email', 'me@me.me'], (err) => { +t.test('npm set', t => { + set.exec(['email', 'me@me.me'], (err) => { if (err) throw err diff --git a/deps/npm/test/lib/shrinkwrap.js b/deps/npm/test/lib/shrinkwrap.js index 51fd7931a1..dc4bc3b220 100644 --- a/deps/npm/test/lib/shrinkwrap.js +++ b/deps/npm/test/lib/shrinkwrap.js @@ -31,7 +31,6 @@ const mocks = { return tree } }, - '../../lib/npm.js': npm, '../../lib/utils/usage.js': () => 'usage instructions', } @@ -80,13 +79,14 @@ t.test('no args', t => { }, } - const shrinkwrap = requireInject('../../lib/shrinkwrap.js', { + const Shrinkwrap = requireInject('../../lib/shrinkwrap.js', { ...mocks, npmlog, '@npmcli/arborist': Arborist, }) + const shrinkwrap = new Shrinkwrap(npm) - shrinkwrap([], err => { + shrinkwrap.exec([], err => { if (err) throw err }) @@ -134,13 +134,14 @@ t.test('no virtual tree', t => { }, } - const shrinkwrap = requireInject('../../lib/shrinkwrap.js', { + const Shrinkwrap = requireInject('../../lib/shrinkwrap.js', { ...mocks, npmlog, '@npmcli/arborist': Arborist, }) + const shrinkwrap = new Shrinkwrap(npm) - shrinkwrap([], err => { + shrinkwrap.exec([], err => { if (err) throw err }) @@ -194,14 +195,15 @@ t.test('existing package-json file', t => { }, } - const shrinkwrap = requireInject('../../lib/shrinkwrap.js', { + const Shrinkwrap = requireInject('../../lib/shrinkwrap.js', { ...mocks, fs, npmlog, '@npmcli/arborist': Arborist, }) + const shrinkwrap = new Shrinkwrap(npm) - shrinkwrap([], err => { + shrinkwrap.exec([], err => { if (err) throw err }) @@ -248,13 +250,14 @@ t.test('update shrinkwrap file version', t => { }, } - const shrinkwrap = requireInject('../../lib/shrinkwrap.js', { + const Shrinkwrap = requireInject('../../lib/shrinkwrap.js', { ...mocks, npmlog, '@npmcli/arborist': Arborist, }) + const shrinkwrap = new Shrinkwrap(npm) - shrinkwrap([], err => { + shrinkwrap.exec([], err => { if (err) throw err }) @@ -301,24 +304,26 @@ t.test('update to date shrinkwrap file', t => { }, } - const shrinkwrap = requireInject('../../lib/shrinkwrap.js', { + const Shrinkwrap = requireInject('../../lib/shrinkwrap.js', { ...mocks, npmlog, '@npmcli/arborist': Arborist, }) + const shrinkwrap = new Shrinkwrap(npm) - shrinkwrap([], err => { + shrinkwrap.exec([], err => { if (err) throw err }) }) t.test('shrinkwrap --global', t => { - const shrinkwrap = requireInject('../../lib/shrinkwrap.js', mocks) + const Shrinkwrap = requireInject('../../lib/shrinkwrap.js', mocks) npm.flatOptions.global = true + const shrinkwrap = new Shrinkwrap(npm) - shrinkwrap([], err => { + shrinkwrap.exec([], err => { t.match( err, /does not work for global packages/, @@ -330,8 +335,11 @@ t.test('shrinkwrap --global', t => { }) t.test('works without fs.promises', async t => { - t.doesNotThrow(() => requireInject('../../lib/shrinkwrap.js', { - ...mocks, - fs: { ...fs, promises: null }, - })) + t.doesNotThrow(() => { + const Shrinkwrap = requireInject('../../lib/shrinkwrap.js', { + ...mocks, + fs: { ...fs, promises: null }, + }) + new Shrinkwrap(npm) + }) }) diff --git a/deps/npm/test/lib/star.js b/deps/npm/test/lib/star.js index ea5e07b94f..64efd9ef8c 100644 --- a/deps/npm/test/lib/star.js +++ b/deps/npm/test/lib/star.js @@ -10,7 +10,6 @@ const npmlog = { error: noop, info: noop, verbose: noop } const mocks = { npmlog, 'npm-registry-fetch': npmFetch, - '../../lib/npm.js': npm, '../../lib/utils/output.js': (...msg) => { result += msg.join('\n') }, @@ -18,7 +17,8 @@ const mocks = { '../../lib/utils/usage.js': () => 'usage instructions', } -const star = requireInject('../../lib/star.js', mocks) +const Star = requireInject('../../lib/star.js', mocks) +const star = new Star(npm) t.afterEach(cb => { npm.config = { get () {} } @@ -29,7 +29,7 @@ t.afterEach(cb => { }) t.test('no args', t => { - star([], err => { + star.exec([], err => { t.match( err, /usage instructions/, @@ -56,7 +56,7 @@ t.test('star a package', t => { t.equal(msg, 'starring', 'should use expected msg') t.equal(id, pkgName, 'should use expected id') } - star([pkgName], err => { + star.exec([pkgName], err => { if (err) throw err t.equal( @@ -84,7 +84,7 @@ t.test('unstar a package', t => { t.equal(msg, 'unstarring', 'should use expected msg') t.equal(id, pkgName, 'should use expected id') } - star([pkgName], err => { + star.exec([pkgName], err => { if (err) throw err t.equal( @@ -99,7 +99,7 @@ t.test('unicode', async t => { t.test('star a package', t => { npm.flatOptions.unicode = true npmFetch.json = async (uri, opts) => ({}) - star(['pkg'], err => { + star.exec(['pkg'], err => { if (err) throw err t.equal( @@ -115,7 +115,7 @@ t.test('unicode', async t => { npm.flatOptions.unicode = true npm.config.get = key => key === 'star.unstar' npmFetch.json = async (uri, opts) => ({}) - star(['pkg'], err => { + star.exec(['pkg'], err => { if (err) throw err t.equal( @@ -129,11 +129,12 @@ t.test('unicode', async t => { }) t.test('logged out user', t => { - const star = requireInject('../../lib/star.js', { + const Star = requireInject('../../lib/star.js', { ...mocks, '../../lib/utils/get-identity.js': async () => undefined, }) - star(['@npmcli/arborist'], err => { + const star = new Star(npm) + star.exec(['@npmcli/arborist'], err => { t.match( err, /You need to be logged in/, diff --git a/deps/npm/test/lib/stars.js b/deps/npm/test/lib/stars.js index ff636a5e54..383b5adf42 100644 --- a/deps/npm/test/lib/stars.js +++ b/deps/npm/test/lib/stars.js @@ -10,7 +10,6 @@ const npmlog = { warn: noop } const mocks = { npmlog, 'npm-registry-fetch': npmFetch, - '../../lib/npm.js': npm, '../../lib/utils/output.js': (...msg) => { result = [result, ...msg].join('\n') }, @@ -18,7 +17,8 @@ const mocks = { '../../lib/utils/usage.js': () => 'usage instructions', } -const stars = requireInject('../../lib/stars.js', mocks) +const Stars = requireInject('../../lib/stars.js', mocks) +const stars = new Stars(npm) t.afterEach(cb => { npm.config = { get () {} } @@ -43,7 +43,7 @@ t.test('no args', t => { } } - stars([], err => { + stars.exec([], err => { if (err) throw err @@ -67,7 +67,7 @@ t.test('npm star <user>', t => { } } - stars(['ruyadorno'], err => { + stars.exec(['ruyadorno'], err => { if (err) throw err @@ -97,7 +97,7 @@ t.test('unauthorized request', t => { ) } - stars([], err => { + stars.exec([], err => { t.match( err, /Not logged in/, @@ -121,7 +121,7 @@ t.test('unexpected error', t => { throw new Error('Should not output extra warning msgs') } - stars([], err => { + stars.exec([], err => { t.match( err, /ERROR/, @@ -144,7 +144,7 @@ t.test('no pkg starred', t => { ) } - stars([], err => { + stars.exec([], err => { if (err) throw err }) diff --git a/deps/npm/test/lib/start.js b/deps/npm/test/lib/start.js index 4f599223d7..9a3328309b 100644 --- a/deps/npm/test/lib/start.js +++ b/deps/npm/test/lib/start.js @@ -1,4 +1,17 @@ const t = require('tap') -const start = require('../../lib/start.js') -t.isa(start, Function) +let runArgs +const npm = { + commands: { + 'run-script': (args, cb) => { + runArgs = args + cb() + }, + }, +} +const Start = require('../../lib/start.js') +const start = new Start(npm) t.equal(start.usage, 'npm start [-- <args>]') +start.exec(['foo'], () => { + t.match(runArgs, ['start', 'foo']) + t.end() +}) diff --git a/deps/npm/test/lib/stop.js b/deps/npm/test/lib/stop.js index 4e26703c93..e6cb193b62 100644 --- a/deps/npm/test/lib/stop.js +++ b/deps/npm/test/lib/stop.js @@ -1,4 +1,17 @@ const t = require('tap') -const stop = require('../../lib/stop.js') -t.isa(stop, Function) +let runArgs +const npm = { + commands: { + 'run-script': (args, cb) => { + runArgs = args + cb() + }, + }, +} +const Stop = require('../../lib/stop.js') +const stop = new Stop(npm) t.equal(stop.usage, 'npm stop [-- <args>]') +stop.exec(['foo'], () => { + t.match(runArgs, ['stop', 'foo']) + t.end() +}) diff --git a/deps/npm/test/lib/team.js b/deps/npm/test/lib/team.js index 9edaf58ee7..a264597258 100644 --- a/deps/npm/test/lib/team.js +++ b/deps/npm/test/lib/team.js @@ -14,7 +14,6 @@ const npm = { flatOptions: {} } const mocks = { libnpmteam, 'cli-columns': a => a.join(' '), - '../../lib/npm.js': npm, '../../lib/utils/output.js': (...msg) => { result += msg.join('\n') }, @@ -28,10 +27,11 @@ t.afterEach(cb => { cb() }) -const team = requireInject('../../lib/team.js', mocks) +const Team = requireInject('../../lib/team.js', mocks) +const team = new Team(npm) t.test('no args', t => { - team([], err => { + team.exec([], err => { t.match( err, 'usage instructions', @@ -43,7 +43,7 @@ t.test('no args', t => { t.test('team add <scope:team> <user>', t => { t.test('default output', t => { - team(['add', '@npmcli:developers', 'foo'], err => { + team.exec(['add', '@npmcli:developers', 'foo'], err => { if (err) throw err @@ -55,7 +55,7 @@ t.test('team add <scope:team> <user>', t => { t.test('--parseable', t => { npm.flatOptions.parseable = true - team(['add', '@npmcli:developers', 'foo'], err => { + team.exec(['add', '@npmcli:developers', 'foo'], err => { if (err) throw err @@ -70,7 +70,7 @@ t.test('team add <scope:team> <user>', t => { t.test('--json', t => { npm.flatOptions.json = true - team(['add', '@npmcli:developers', 'foo'], err => { + team.exec(['add', '@npmcli:developers', 'foo'], err => { if (err) throw err @@ -90,7 +90,7 @@ t.test('team add <scope:team> <user>', t => { t.test('--silent', t => { npm.flatOptions.silent = true - team(['add', '@npmcli:developers', 'foo'], err => { + team.exec(['add', '@npmcli:developers', 'foo'], err => { if (err) throw err @@ -104,7 +104,7 @@ t.test('team add <scope:team> <user>', t => { t.test('team create <scope:team>', t => { t.test('default output', t => { - team(['create', '@npmcli:newteam'], err => { + team.exec(['create', '@npmcli:newteam'], err => { if (err) throw err @@ -116,7 +116,7 @@ t.test('team create <scope:team>', t => { t.test('--parseable', t => { npm.flatOptions.parseable = true - team(['create', '@npmcli:newteam'], err => { + team.exec(['create', '@npmcli:newteam'], err => { if (err) throw err @@ -131,7 +131,7 @@ t.test('team create <scope:team>', t => { t.test('--json', t => { npm.flatOptions.json = true - team(['create', '@npmcli:newteam'], err => { + team.exec(['create', '@npmcli:newteam'], err => { if (err) throw err @@ -150,7 +150,7 @@ t.test('team create <scope:team>', t => { t.test('--silent', t => { npm.flatOptions.silent = true - team(['create', '@npmcli:newteam'], err => { + team.exec(['create', '@npmcli:newteam'], err => { if (err) throw err @@ -164,7 +164,7 @@ t.test('team create <scope:team>', t => { t.test('team destroy <scope:team>', t => { t.test('default output', t => { - team(['destroy', '@npmcli:newteam'], err => { + team.exec(['destroy', '@npmcli:newteam'], err => { if (err) throw err @@ -176,7 +176,7 @@ t.test('team destroy <scope:team>', t => { t.test('--parseable', t => { npm.flatOptions.parseable = true - team(['destroy', '@npmcli:newteam'], err => { + team.exec(['destroy', '@npmcli:newteam'], err => { if (err) throw err @@ -188,7 +188,7 @@ t.test('team destroy <scope:team>', t => { t.test('--json', t => { npm.flatOptions.json = true - team(['destroy', '@npmcli:newteam'], err => { + team.exec(['destroy', '@npmcli:newteam'], err => { if (err) throw err @@ -207,7 +207,7 @@ t.test('team destroy <scope:team>', t => { t.test('--silent', t => { npm.flatOptions.silent = true - team(['destroy', '@npmcli:newteam'], err => { + team.exec(['destroy', '@npmcli:newteam'], err => { if (err) throw err @@ -230,13 +230,14 @@ t.test('team ls <scope>', t => { }, } - const team = requireInject('../../lib/team.js', { + const Team = requireInject('../../lib/team.js', { ...mocks, libnpmteam, }) + const team = new Team(npm) t.test('default output', t => { - team(['ls', '@npmcli'], err => { + team.exec(['ls', '@npmcli'], err => { if (err) throw err @@ -248,7 +249,7 @@ t.test('team ls <scope>', t => { t.test('--parseable', t => { npm.flatOptions.parseable = true - team(['ls', '@npmcli'], err => { + team.exec(['ls', '@npmcli'], err => { if (err) throw err @@ -260,7 +261,7 @@ t.test('team ls <scope>', t => { t.test('--json', t => { npm.flatOptions.json = true - team(['ls', '@npmcli'], err => { + team.exec(['ls', '@npmcli'], err => { if (err) throw err @@ -280,7 +281,7 @@ t.test('team ls <scope>', t => { t.test('--silent', t => { npm.flatOptions.silent = true - team(['ls', '@npmcli'], err => { + team.exec(['ls', '@npmcli'], err => { if (err) throw err @@ -296,12 +297,13 @@ t.test('team ls <scope>', t => { }, } - const team = requireInject('../../lib/team.js', { + const Team = requireInject('../../lib/team.js', { ...mocks, libnpmteam, }) + const team = new Team(npm) - team(['ls', '@npmcli'], err => { + team.exec(['ls', '@npmcli'], err => { if (err) throw err @@ -317,12 +319,13 @@ t.test('team ls <scope>', t => { }, } - const team = requireInject('../../lib/team.js', { + const Team = requireInject('../../lib/team.js', { ...mocks, libnpmteam, }) + const team = new Team(npm) - team(['ls', '@npmcli'], err => { + team.exec(['ls', '@npmcli'], err => { if (err) throw err @@ -340,13 +343,14 @@ t.test('team ls <scope:team>', t => { return ['nlf', 'ruyadorno', 'darcyclarke', 'isaacs'] }, } - const team = requireInject('../../lib/team.js', { + const Team = requireInject('../../lib/team.js', { ...mocks, libnpmteam, }) + const team = new Team(npm) t.test('default output', t => { - team(['ls', '@npmcli:developers'], err => { + team.exec(['ls', '@npmcli:developers'], err => { if (err) throw err @@ -358,7 +362,7 @@ t.test('team ls <scope:team>', t => { t.test('--parseable', t => { npm.flatOptions.parseable = true - team(['ls', '@npmcli:developers'], err => { + team.exec(['ls', '@npmcli:developers'], err => { if (err) throw err @@ -370,7 +374,7 @@ t.test('team ls <scope:team>', t => { t.test('--json', t => { npm.flatOptions.json = true - team(['ls', '@npmcli:developers'], err => { + team.exec(['ls', '@npmcli:developers'], err => { if (err) throw err @@ -391,7 +395,7 @@ t.test('team ls <scope:team>', t => { t.test('--silent', t => { npm.flatOptions.silent = true - team(['ls', '@npmcli:developers'], err => { + team.exec(['ls', '@npmcli:developers'], err => { if (err) throw err @@ -407,12 +411,13 @@ t.test('team ls <scope:team>', t => { }, } - const team = requireInject('../../lib/team.js', { + const Team = requireInject('../../lib/team.js', { ...mocks, libnpmteam, }) + const team = new Team(npm) - team(['ls', '@npmcli:developers'], err => { + team.exec(['ls', '@npmcli:developers'], err => { if (err) throw err @@ -428,12 +433,13 @@ t.test('team ls <scope:team>', t => { }, } - const team = requireInject('../../lib/team.js', { + const Team = requireInject('../../lib/team.js', { ...mocks, libnpmteam, }) + const team = new Team(npm) - team(['ls', '@npmcli:developers'], err => { + team.exec(['ls', '@npmcli:developers'], err => { if (err) throw err @@ -447,7 +453,7 @@ t.test('team ls <scope:team>', t => { t.test('team rm <scope:team> <user>', t => { t.test('default output', t => { - team(['rm', '@npmcli:newteam', 'foo'], err => { + team.exec(['rm', '@npmcli:newteam', 'foo'], err => { if (err) throw err @@ -459,7 +465,7 @@ t.test('team rm <scope:team> <user>', t => { t.test('--parseable', t => { npm.flatOptions.parseable = true - team(['rm', '@npmcli:newteam', 'foo'], err => { + team.exec(['rm', '@npmcli:newteam', 'foo'], err => { if (err) throw err @@ -471,7 +477,7 @@ t.test('team rm <scope:team> <user>', t => { t.test('--json', t => { npm.flatOptions.json = true - team(['rm', '@npmcli:newteam', 'foo'], err => { + team.exec(['rm', '@npmcli:newteam', 'foo'], err => { if (err) throw err @@ -491,7 +497,7 @@ t.test('team rm <scope:team> <user>', t => { t.test('--silent', t => { npm.flatOptions.silent = true - team(['rm', '@npmcli:newteam', 'foo'], err => { + team.exec(['rm', '@npmcli:newteam', 'foo'], err => { if (err) throw err diff --git a/deps/npm/test/lib/test.js b/deps/npm/test/lib/test.js index 6f4a7395d7..f6f3d7afb8 100644 --- a/deps/npm/test/lib/test.js +++ b/deps/npm/test/lib/test.js @@ -1,7 +1,7 @@ const t = require('tap') const requireInject = require('require-inject') let RUN_ARGS = null -const npmock = { +const npm = { commands: { 'run-script': (args, cb) => { RUN_ARGS = args @@ -9,15 +9,14 @@ const npmock = { }, }, } -const test = requireInject('../../lib/test.js', { - '../../lib/npm.js': npmock, -}) +const Test = requireInject('../../lib/test.js') +const test = new Test(npm) t.test('run a test', t => { - test([], (er) => { + test.exec([], (er) => { t.strictSame(RUN_ARGS, ['test'], 'added "test" to the args') }) - test(['hello', 'world'], (er) => { + test.exec(['hello', 'world'], (er) => { t.strictSame(RUN_ARGS, ['test', 'hello', 'world'], 'added positional args') }) @@ -26,13 +25,13 @@ t.test('run a test', t => { }) const otherErr = new Error('should see this') - npmock.commands['run-script'] = (args, cb) => cb(lcErr) - test([], (er) => { + npm.commands['run-script'] = (args, cb) => cb(lcErr) + test.exec([], (er) => { t.equal(er, 'Test failed. See above for more details.') }) - npmock.commands['run-script'] = (args, cb) => cb(otherErr) - test([], (er) => { + npm.commands['run-script'] = (args, cb) => cb(otherErr) + test.exec([], (er) => { t.match(er, { message: 'should see this' }) }) diff --git a/deps/npm/test/lib/token.js b/deps/npm/test/lib/token.js index 6ab841f499..412d2746be 100644 --- a/deps/npm/test/lib/token.js +++ b/deps/npm/test/lib/token.js @@ -2,15 +2,13 @@ const { test } = require('tap') const requireInject = require('require-inject') const mocks = { - npm: {}, profile: {}, output: () => {}, log: {}, readUserInfo: {}, } -const tokenMock = requireInject('../../lib/token.js', { - '../../lib/npm.js': mocks.npm, +const Token = requireInject('../../lib/token.js', { '../../lib/utils/output.js': (...args) => mocks.output(...args), '../../lib/utils/otplease.js': (opts, fn) => { return Promise.resolve().then(() => fn(opts)) @@ -19,36 +17,42 @@ const tokenMock = requireInject('../../lib/token.js', { 'npm-profile': mocks.profile, npmlog: mocks.log, }) +const token = new Token({}) const tokenWithMocks = (mockRequests) => { for (const mod in mockRequests) { - if (typeof mockRequests[mod] === 'function') - mocks[mod] = mockRequests[mod] - else { - for (const key in mockRequests[mod]) - mocks[mod][key] = mockRequests[mod][key] + if (mod !== 'npm') { + if (typeof mockRequests[mod] === 'function') + mocks[mod] = mockRequests[mod] + else { + for (const key in mockRequests[mod]) + mocks[mod][key] = mockRequests[mod][key] + } } } const reset = () => { for (const mod in mockRequests) { - if (typeof mockRequests[mod] === 'function') - mocks[mod] = () => {} - else { - for (const key in mockRequests[mod]) - delete mocks[mod][key] + if (mod !== 'npm') { + if (typeof mockRequests[mod] === 'function') + mocks[mod] = () => {} + else { + for (const key in mockRequests[mod]) + delete mocks[mod][key] + } } } } - return [tokenMock, reset] + const token = new Token(mockRequests.npm || {}) + return [token, reset] } test('completion', (t) => { t.plan(5) const testComp = (argv, expect) => { - t.resolveMatch(tokenMock.completion({ conf: { argv: { remain: argv } } }), expect, argv.join(' ')) + t.resolveMatch(token.completion({ conf: { argv: { remain: argv } } }), expect, argv.join(' ')) } testComp(['npm', 'token'], ['list', 'revoke', 'create']) @@ -57,7 +61,7 @@ test('completion', (t) => { testComp(['npm', 'token', 'create'], []) t.rejects( - tokenMock.completion({ conf: { argv: { remain: ['npm', 'token', 'foobar'] } } }), + token.completion({ conf: { argv: { remain: ['npm', 'token', 'foobar'] } } }), { message: 'foobar not recognize' } ) }) @@ -77,7 +81,7 @@ test('token foobar', (t) => { t.tearDown(reset) - tokenMock(['foobar'], (err) => { + token.exec(['foobar'], (err) => { t.match(err.message, 'foobar is not a recognized subcommand') }) }) @@ -145,7 +149,7 @@ test('token list', (t) => { t.tearDown(reset) - token([], (err) => { + token.exec([], (err) => { t.ifError(err, 'npm token list') }) }) @@ -199,7 +203,7 @@ test('token list json output', (t) => { t.tearDown(reset) - token(['list'], (err) => { + token.exec(['list'], (err) => { t.ifError(err, 'npm token list') }) }) @@ -267,7 +271,7 @@ test('token list parseable output', (t) => { t.tearDown(reset) - token(['list'], (err) => { + token.exec(['list'], (err) => { t.ifError(err, 'npm token list') }) }) @@ -320,7 +324,7 @@ test('token revoke', (t) => { t.tearDown(reset) - token(['rm', 'abcd'], (err) => { + token.exec(['rm', 'abcd'], (err) => { t.ifError(err, 'npm token rm') }) }) @@ -372,7 +376,7 @@ test('token revoke multiple tokens', (t) => { t.tearDown(reset) - token(['revoke', 'abcd', 'efgh'], (err) => { + token.exec(['revoke', 'abcd', 'efgh'], (err) => { t.ifError(err, 'npm token rm') }) }) @@ -424,7 +428,7 @@ test('token revoke json output', (t) => { t.tearDown(reset) - token(['delete', 'abcd'], (err) => { + token.exec(['delete', 'abcd'], (err) => { t.ifError(err, 'npm token rm') }) }) @@ -474,7 +478,7 @@ test('token revoke parseable output', (t) => { t.tearDown(reset) - token(['remove', 'abcd'], (err) => { + token.exec(['remove', 'abcd'], (err) => { t.ifError(err, 'npm token rm') }) }) @@ -524,7 +528,7 @@ test('token revoke by token', (t) => { t.tearDown(reset) - token(['rm', 'efgh5678'], (err) => { + token.exec(['rm', 'efgh5678'], (err) => { t.ifError(err, 'npm token rm') }) }) @@ -544,7 +548,7 @@ test('token revoke requires an id', (t) => { t.tearDown(reset) - token(['rm'], (err) => { + token.exec(['rm'], (err) => { t.match(err.message, '`<tokenKey>` argument is required') }) }) @@ -589,7 +593,7 @@ test('token revoke ambiguous id errors', (t) => { t.tearDown(reset) - token(['rm', 'abcd'], (err) => { + token.exec(['rm', 'abcd'], (err) => { t.match(err.message, 'Token ID "abcd" was ambiguous') }) }) @@ -633,7 +637,7 @@ test('token revoke unknown id errors', (t) => { t.tearDown(reset) - token(['rm', 'efgh'], (err) => { + token.exec(['rm', 'efgh'], (err) => { t.match(err.message, 'Unknown token id or value "efgh".') }) }) @@ -697,7 +701,7 @@ test('token create', (t) => { t.tearDown(reset) - token(['create'], (err) => { + token.exec(['create'], (err) => { t.ifError(err, 'npm token create') }) }) @@ -756,7 +760,7 @@ test('token create json output', (t) => { t.tearDown(reset) - token(['create'], (err) => { + token.exec(['create'], (err) => { t.ifError(err, 'npm token create') }) }) @@ -822,7 +826,7 @@ test('token create parseable output', (t) => { t.tearDown(reset) - token(['create'], (err) => { + token.exec(['create'], (err) => { t.ifError(err, 'npm token create') }) }) @@ -856,7 +860,7 @@ test('token create ipv6 cidr', (t) => { t.tearDown(reset) - token(['create'], (err) => { + token.exec(['create'], (err) => { t.equal(err.message, 'CIDR whitelist can only contain IPv4 addresses, ::1/128 is IPv6', 'returns correct error') t.equal(err.code, 'EINVALIDCIDR') }) @@ -891,7 +895,7 @@ test('token create invalid cidr', (t) => { t.tearDown(reset) - token(['create'], (err) => { + token.exec(['create'], (err) => { t.equal(err.message, 'CIDR whitelist contains invalid CIDR entry: apple/cider', 'returns correct error') t.equal(err.code, 'EINVALIDCIDR') }) diff --git a/deps/npm/test/lib/uninstall.js b/deps/npm/test/lib/uninstall.js index 69040c0f25..c62b59950b 100644 --- a/deps/npm/test/lib/uninstall.js +++ b/deps/npm/test/lib/uninstall.js @@ -12,12 +12,12 @@ const npm = { localPrefix: '', } const mocks = { - '../../lib/npm.js': npm, '../../lib/utils/reify-finish.js': () => Promise.resolve(), '../../lib/utils/usage.js': () => 'usage instructions', } -const uninstall = requireInject('../../lib/uninstall.js', mocks) +const Uninstall = requireInject('../../lib/uninstall.js', mocks) +const uninstall = new Uninstall(npm) t.afterEach(cb => { npm.globalDir = '' @@ -87,7 +87,7 @@ t.test('remove single installed lib', t => { npm.flatOptions.prefix = path - uninstall(['b'], err => { + uninstall.exec(['b'], err => { if (err) throw err @@ -150,7 +150,7 @@ t.test('remove multiple installed libs', t => { npm.flatOptions.prefix = path - uninstall(['b'], err => { + uninstall.exec(['b'], err => { if (err) throw err @@ -165,7 +165,7 @@ t.test('no args local', t => { npm.flatOptions.prefix = path - uninstall([], err => { + uninstall.exec([], err => { t.match( err, /Must provide a package name to remove/, @@ -201,7 +201,7 @@ t.test('no args global', t => { const a = resolve(path, 'lib/node_modules/a') t.ok(() => fs.statSync(a)) - uninstall([], err => { + uninstall.exec([], err => { if (err) throw err @@ -218,7 +218,7 @@ t.test('no args global but no package.json', t => { npm.localPrefix = path npm.flatOptions.global = true - uninstall([], err => { + uninstall.exec([], err => { t.match( err, 'usage instructions', @@ -232,16 +232,17 @@ t.test('no args global but no package.json', t => { t.test('unknown error reading from localPrefix package.json', t => { const path = t.testdir({}) - const uninstall = requireInject('../../lib/uninstall.js', { + const Uninstall = requireInject('../../lib/uninstall.js', { ...mocks, 'read-package-json-fast': () => Promise.reject(new Error('ERR')), }) + const uninstall = new Uninstall(npm) npm.prefix = path npm.localPrefix = path npm.flatOptions.global = true - uninstall([], err => { + uninstall.exec([], err => { t.match( err, /ERR/, diff --git a/deps/npm/test/lib/unpublish.js b/deps/npm/test/lib/unpublish.js index c1fbed57eb..80a879cb6e 100644 --- a/deps/npm/test/lib/unpublish.js +++ b/deps/npm/test/lib/unpublish.js @@ -18,7 +18,6 @@ const mocks = { 'npm-package-arg': noop, 'npm-registry-fetch': { json: noop }, 'read-package-json': cb => cb(), - '../../lib/npm.js': npm, '../../lib/utils/output.js': (...msg) => { result += msg.join('\n') }, @@ -78,7 +77,7 @@ t.test('no args --force', t => { }, } - const unpublish = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, npmlog, libnpmpublish, @@ -88,8 +87,9 @@ t.test('no args --force', t => { version: '1.0.0', }), }) + const unpublish = new Unpublish(npm) - unpublish([], err => { + unpublish.exec([], err => { if (err) throw err @@ -104,15 +104,16 @@ t.test('no args --force', t => { t.test('no args --force missing package.json', t => { npm.flatOptions.force = true - const unpublish = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, 'read-package-json': (path, cb) => cb(Object.assign( new Error('ENOENT'), { code: 'ENOENT' } )), }) + const unpublish = new Unpublish(npm) - unpublish([], err => { + unpublish.exec([], err => { t.match( err, /usage instructions/, @@ -125,12 +126,13 @@ t.test('no args --force missing package.json', t => { t.test('no args --force unknown error reading package.json', t => { npm.flatOptions.force = true - const unpublish = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, 'read-package-json': (path, cb) => cb(new Error('ERR')), }) + const unpublish = new Unpublish(npm) - unpublish([], err => { + unpublish.exec([], err => { t.match( err, /ERR/, @@ -141,11 +143,12 @@ t.test('no args --force unknown error reading package.json', t => { }) t.test('no args', t => { - const unpublish = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, }) + const unpublish = new Unpublish(npm) - unpublish([], err => { + unpublish.exec([], err => { t.match( err, /Refusing to delete entire project/, @@ -156,11 +159,12 @@ t.test('no args', t => { }) t.test('too many args', t => { - const unpublish = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, }) + const unpublish = new Unpublish(npm) - unpublish(['a', 'b'], err => { + unpublish.exec(['a', 'b'], err => { t.match( err, /usage instructions/, @@ -206,14 +210,15 @@ t.test('unpublish <pkg>@version', t => { }, } - const unpublish = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, npmlog, libnpmpublish, 'npm-package-arg': npa, }) + const unpublish = new Unpublish(npm) - unpublish(['pkg@1.0.0'], err => { + unpublish.exec(['pkg@1.0.0'], err => { if (err) throw err @@ -235,15 +240,16 @@ t.test('no version found in package.json', t => { npa.resolve = () => '' - const unpublish = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, 'npm-package-arg': npa, 'read-package-json': (path, cb) => cb(null, { name: 'pkg', }), }) + const unpublish = new Unpublish(npm) - unpublish([], err => { + unpublish.exec([], err => { if (err) throw err @@ -259,7 +265,7 @@ t.test('no version found in package.json', t => { t.test('unpublish <pkg> --force no version set', t => { npm.flatOptions.force = true - const unpublish = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, 'npm-package-arg': () => ({ name: 'pkg', @@ -267,8 +273,9 @@ t.test('unpublish <pkg> --force no version set', t => { type: 'tag', }), }) + const unpublish = new Unpublish(npm) - unpublish(['pkg'], err => { + unpublish.exec(['pkg'], err => { if (err) throw err @@ -292,12 +299,13 @@ t.test('silent', t => { npa.resolve = () => '' - const unpublish = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, 'npm-package-arg': npa, }) + const unpublish = new Unpublish(npm) - unpublish(['pkg@1.0.0'], err => { + unpublish.exec(['pkg@1.0.0'], err => { if (err) throw err @@ -312,13 +320,15 @@ t.test('silent', t => { t.test('completion', async t => { const testComp = - async (t, { completion, argv, partialWord, expect, title }) => { - const res = await completion({conf: {argv: {remain: argv}}, partialWord}) + async (t, { unpublish, argv, partialWord, expect, title }) => { + const res = await unpublish.completion( + {conf: {argv: {remain: argv}}, partialWord} + ) t.strictSame(res, expect, title || argv.join(' ')) } t.test('completing with multiple versions from the registry', async t => { - const { completion } = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, libnpmaccess: { async lsPackages () { @@ -341,9 +351,10 @@ t.test('completion', async t => { }, }, }) + const unpublish = new Unpublish(npm) await testComp(t, { - completion, + unpublish, argv: ['npm', 'unpublish'], partialWord: 'pkg', expect: [ @@ -355,7 +366,7 @@ t.test('completion', async t => { }) t.test('no versions retrieved', async t => { - const { completion } = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, libnpmaccess: { async lsPackages () { @@ -374,9 +385,10 @@ t.test('completion', async t => { }, }, }) + const unpublish = new Unpublish(npm) await testComp(t, { - completion, + unpublish, argv: ['npm', 'unpublish'], partialWord: 'pkg', expect: [ @@ -387,7 +399,7 @@ t.test('completion', async t => { }) t.test('packages starting with same letters', async t => { - const { completion } = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, libnpmaccess: { async lsPackages () { @@ -400,9 +412,10 @@ t.test('completion', async t => { }, 'npm-package-arg': require('npm-package-arg'), }) + const unpublish = new Unpublish(npm) await testComp(t, { - completion, + unpublish, argv: ['npm', 'unpublish'], partialWord: 'pkg', expect: [ @@ -414,7 +427,7 @@ t.test('completion', async t => { }) t.test('no packages retrieved', async t => { - const { completion } = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, libnpmaccess: { async lsPackages () { @@ -422,9 +435,10 @@ t.test('completion', async t => { }, }, }) + const unpublish = new Unpublish(npm) await testComp(t, { - completion, + unpublish, argv: ['npm', 'unpublish'], partialWord: 'pkg', expect: [], @@ -433,7 +447,7 @@ t.test('completion', async t => { }) t.test('no pkg name to complete', async t => { - const { completion } = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, libnpmaccess: { async lsPackages () { @@ -444,9 +458,10 @@ t.test('completion', async t => { }, }, }) + const unpublish = new Unpublish(npm) await testComp(t, { - completion, + unpublish, argv: ['npm', 'unpublish'], partialWord: undefined, expect: ['pkg', 'bar'], @@ -455,7 +470,7 @@ t.test('completion', async t => { }) t.test('no pkg names retrieved from user account', async t => { - const { completion } = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, libnpmaccess: { async lsPackages () { @@ -463,9 +478,10 @@ t.test('completion', async t => { }, }, }) + const unpublish = new Unpublish(npm) await testComp(t, { - completion, + unpublish, argv: ['npm', 'unpublish'], partialWord: 'pkg', expect: [], @@ -474,13 +490,14 @@ t.test('completion', async t => { }) t.test('logged out user', async t => { - const { completion } = requireInject('../../lib/unpublish.js', { + const Unpublish = requireInject('../../lib/unpublish.js', { ...mocks, '../../lib/utils/get-identity.js': () => Promise.reject(new Error('ERR')), }) + const unpublish = new Unpublish(npm) await testComp(t, { - completion, + unpublish, argv: ['npm', 'unpublish'], partialWord: 'pkg', expect: [], @@ -488,10 +505,11 @@ t.test('completion', async t => { }) t.test('too many args', async t => { - const { completion } = requireInject('../../lib/unpublish.js', mocks) + const Unpublish = requireInject('../../lib/unpublish.js', mocks) + const unpublish = new Unpublish(npm) await testComp(t, { - completion, + unpublish, argv: ['npm', 'unpublish', 'foo'], partialWord: undefined, expect: [], diff --git a/deps/npm/test/lib/unstar.js b/deps/npm/test/lib/unstar.js index 63b2028a18..3f3487176d 100644 --- a/deps/npm/test/lib/unstar.js +++ b/deps/npm/test/lib/unstar.js @@ -4,24 +4,30 @@ const t = require('tap') t.test('unstar', t => { t.plan(3) - const unstar = requireInject('../../lib/unstar.js', { - '../../lib/npm.js': { - config: { - set: (key, value) => { - t.equal(key, 'star.unstar', 'should set unstar config value') - t.equal(value, true, 'should set a truthy value') - }, - }, - commands: { - star: (args, cb) => { - t.deepEqual(args, ['pkg'], 'should forward packages') - cb() - }, + class Star { + constructor (npm) { + this.npm = npm + } + + exec (args, cb) { + t.deepEqual(args, ['pkg'], 'should forward packages') + cb() + } + } + const Unstar = requireInject('../../lib/unstar.js', { + '../../lib/star.js': Star, + }) + + const unstar = new Unstar({ + config: { + set: (key, value) => { + t.equal(key, 'star.unstar', 'should set unstar config value') + t.equal(value, true, 'should set a truthy value') }, }, }) - unstar(['pkg'], err => { + unstar.exec(['pkg'], err => { if (err) throw err }) diff --git a/deps/npm/test/lib/update.js b/deps/npm/test/lib/update.js index 993fbbab56..15195573f5 100644 --- a/deps/npm/test/lib/update.js +++ b/deps/npm/test/lib/update.js @@ -16,7 +16,6 @@ const mocks = { '@npmcli/arborist': class { reify () {} }, - '../../lib/npm.js': npm, '../../lib/utils/reify-finish.js': noop, '../../lib/utils/usage.js': () => 'usage instructions', } @@ -47,15 +46,16 @@ t.test('no args', t => { } } - const update = requireInject('../../lib/update.js', { + const Update = requireInject('../../lib/update.js', { ...mocks, - '../../lib/utils/reify-finish.js': (arb) => { + '../../lib/utils/reify-finish.js': (npm, arb) => { t.isLike(arb, Arborist, 'should reify-finish with arborist instance') }, '@npmcli/arborist': Arborist, }) + const update = new Update(npm) - update([], err => { + update.exec([], err => { if (err) throw err }) @@ -80,15 +80,16 @@ t.test('with args', t => { } } - const update = requireInject('../../lib/update.js', { + const Update = requireInject('../../lib/update.js', { ...mocks, - '../../lib/utils/reify-finish.js': (arb) => { + '../../lib/utils/reify-finish.js': (npm, arb) => { t.isLike(arb, Arborist, 'should reify-finish with arborist instance') }, '@npmcli/arborist': Arborist, }) + const update = new Update(npm) - update(['ipt'], err => { + update.exec(['ipt'], err => { if (err) throw err }) @@ -100,7 +101,7 @@ t.test('update --depth=<number>', t => { npm.prefix = '/project/a' npm.flatOptions.depth = 1 - const update = requireInject('../../lib/update.js', { + const Update = requireInject('../../lib/update.js', { ...mocks, npmlog: { warn: (title, msg) => { @@ -113,8 +114,9 @@ t.test('update --depth=<number>', t => { }, }, }) + const update = new Update(npm) - update([], err => { + update.exec([], err => { if (err) throw err }) @@ -150,12 +152,13 @@ t.test('update --global', t => { reify () {} } - const update = requireInject('../../lib/update.js', { + const Update = requireInject('../../lib/update.js', { ...mocks, '@npmcli/arborist': Arborist, }) + const update = new Update(npm) - update([], err => { + update.exec([], err => { if (err) throw err }) diff --git a/deps/npm/test/lib/utils/audit-error.js b/deps/npm/test/lib/utils/audit-error.js index cc5f4c006e..ea7c84373e 100644 --- a/deps/npm/test/lib/utils/audit-error.js +++ b/deps/npm/test/lib/utils/audit-error.js @@ -12,7 +12,6 @@ const npm = { const OUTPUT = [] const output = (...msg) => OUTPUT.push(msg) const auditError = requireInject('../../../lib/utils/audit-error.js', { - '../../../lib/npm.js': npm, '../../../lib/utils/output.js': output, }) @@ -25,7 +24,7 @@ t.afterEach(cb => { t.test('no error, not audit command', t => { npm.command = 'install' - t.equal(auditError({}), false, 'no error') + t.equal(auditError(npm, {}), false, 'no error') t.strictSame(OUTPUT, [], 'no output') t.strictSame(LOGS, [], 'no warnings') t.end() @@ -33,7 +32,7 @@ t.test('no error, not audit command', t => { t.test('error, not audit command', t => { npm.command = 'install' - t.equal(auditError({ + t.equal(auditError(npm, { error: { message: 'message', body: Buffer.from('body'), @@ -53,7 +52,7 @@ t.test('error, not audit command', t => { t.test('error, audit command, not json', t => { npm.command = 'audit' npm.flatOptions.json = false - t.throws(() => auditError({ + t.throws(() => auditError(npm, { error: { message: 'message', body: Buffer.from('body'), @@ -74,7 +73,7 @@ t.test('error, audit command, not json', t => { t.test('error, audit command, json', t => { npm.command = 'audit' npm.flatOptions.json = true - t.throws(() => auditError({ + t.throws(() => auditError(npm, { error: { message: 'message', body: { response: 'body' }, diff --git a/deps/npm/test/lib/utils/completion/installed-deep.js b/deps/npm/test/lib/utils/completion/installed-deep.js index bd61ab4280..0e80a5a198 100644 --- a/deps/npm/test/lib/utils/completion/installed-deep.js +++ b/deps/npm/test/lib/utils/completion/installed-deep.js @@ -12,22 +12,21 @@ const _flatOptions = { }, } const p = '../../../../lib/utils/completion/installed-deep.js' -const installedDeep = requireInject(p, { - '../../../../lib/npm.js': { - flatOptions: _flatOptions, - get prefix () { - return _flatOptions.prefix - }, - get globalDir () { - return globalDir - }, - config: { - get (key) { - return _flatOptions[key] - }, +const installedDeep = requireInject(p) +const npm = { + flatOptions: _flatOptions, + get prefix () { + return _flatOptions.prefix + }, + get globalDir () { + return globalDir + }, + config: { + get (key) { + return _flatOptions[key] }, }, -}) +} const fixture = { 'package.json': JSON.stringify({ @@ -154,7 +153,7 @@ test('get list of package names', async t => { prefix = resolve(fix, 'local') globalDir = resolve(fix, 'global/node_modules') - const res = await installedDeep(null) + const res = await installedDeep(npm, null) t.deepEqual( res, [ @@ -181,7 +180,7 @@ test('get list of package names as global', async t => { _flatOptions.global = true - const res = await installedDeep(null) + const res = await installedDeep(npm, null) t.deepEqual( res, [ @@ -206,7 +205,7 @@ test('limit depth', async t => { _flatOptions.depth = 0 - const res = await installedDeep(null) + const res = await installedDeep(npm, null) t.deepEqual( res, [ @@ -235,7 +234,7 @@ test('limit depth as global', async t => { _flatOptions.global = true _flatOptions.depth = 0 - const res = await installedDeep(null) + const res = await installedDeep(npm, null) t.deepEqual( res, [ diff --git a/deps/npm/test/lib/utils/completion/installed-shallow.js b/deps/npm/test/lib/utils/completion/installed-shallow.js index 1da68810b5..1067a50acd 100644 --- a/deps/npm/test/lib/utils/completion/installed-shallow.js +++ b/deps/npm/test/lib/utils/completion/installed-shallow.js @@ -5,9 +5,7 @@ const t = require('tap') const { resolve } = require('path') const p = '../../../../lib/utils/completion/installed-shallow.js' -const installed = requireInject(p, { - '../../../../lib/npm.js': npm, -}) +const installed = requireInject(p) t.test('global not set, include globals with -g', async t => { const dir = t.testdir({ @@ -32,7 +30,7 @@ t.test('global not set, include globals with -g', async t => { npm.localDir = resolve(dir, 'local/node_modules') flatOptions.global = false const opt = { conf: { argv: { remain: [] } } } - const res = await installed(opt) + const res = await installed(npm, opt) t.strictSame(res.sort(), [ '@scope/y -g', 'x -g', @@ -65,7 +63,7 @@ t.test('global set, include globals and not locals', async t => { npm.localDir = resolve(dir, 'local/node_modules') flatOptions.global = true const opt = { conf: { argv: { remain: [] } } } - const res = await installed(opt) + const res = await installed(npm, opt) t.strictSame(res.sort(), [ '@scope/y', 'x', @@ -96,7 +94,7 @@ t.test('more than 3 items in argv, skip it', async t => { npm.localDir = resolve(dir, 'local/node_modules') flatOptions.global = false const opt = { conf: { argv: { remain: [1, 2, 3, 4, 5, 6] } } } - const res = await installed(opt) + const res = await installed(npm, opt) t.strictSame(res, null) t.end() }) diff --git a/deps/npm/test/lib/utils/explain-dep.js b/deps/npm/test/lib/utils/explain-dep.js index 1b8c4ae380..1fee610508 100644 --- a/deps/npm/test/lib/utils/explain-dep.js +++ b/deps/npm/test/lib/utils/explain-dep.js @@ -107,6 +107,7 @@ const cases = { type: 'prod', name: 'prod-dep', spec: '1.x', + bundled: true, from: { location: '/path/to/project', }, diff --git a/deps/npm/test/lib/utils/get-identity.js b/deps/npm/test/lib/utils/get-identity.js index 8a4de88352..cc713b3378 100644 --- a/deps/npm/test/lib/utils/get-identity.js +++ b/deps/npm/test/lib/utils/get-identity.js @@ -3,12 +3,10 @@ const requireInject = require('require-inject') test('throws ENOREGISTRY when no registry option is provided', async (t) => { t.plan(2) - const getIdentity = requireInject('../../../lib/utils/get-identity.js', { - '../../../lib/npm.js': {}, - }) + const getIdentity = requireInject('../../../lib/utils/get-identity.js') try { - await getIdentity() + await getIdentity({}) } catch (err) { t.equal(err.code, 'ENOREGISTRY', 'assigns the appropriate error code') t.equal(err.message, 'No registry specified.', 'returns the correct error message') @@ -18,17 +16,16 @@ test('throws ENOREGISTRY when no registry option is provided', async (t) => { test('returns username from uri when provided', async (t) => { t.plan(1) - const getIdentity = requireInject('../../../lib/utils/get-identity.js', { - '../../../lib/npm.js': { - config: { - getCredentialsByURI: () => { - return { username: 'foo' } - }, + const getIdentity = requireInject('../../../lib/utils/get-identity.js') + const npm = { + config: { + getCredentialsByURI: () => { + return { username: 'foo' } }, }, - }) + } - const identity = await getIdentity({ registry: 'https://registry.npmjs.org' }) + const identity = await getIdentity(npm, { registry: 'https://registry.npmjs.org' }) t.equal(identity, 'foo', 'returns username from uri') }) @@ -41,11 +38,6 @@ test('calls registry whoami when token is provided', async (t) => { } const getIdentity = requireInject('../../../lib/utils/get-identity.js', { - '../../../lib/npm.js': { - config: { - getCredentialsByURI: () => options, - }, - }, 'npm-registry-fetch': { json: (path, opts) => { t.equal(path, '/-/whoami', 'calls whoami') @@ -54,8 +46,13 @@ test('calls registry whoami when token is provided', async (t) => { }, }, }) + const npm = { + config: { + getCredentialsByURI: () => options, + }, + } - const identity = await getIdentity(options) + const identity = await getIdentity(npm, options) t.equal(identity, 'foo', 'fetched username from registry') }) @@ -68,11 +65,6 @@ test('throws ENEEDAUTH when response does not include a username', async (t) => } const getIdentity = requireInject('../../../lib/utils/get-identity.js', { - '../../../lib/npm.js': { - config: { - getCredentialsByURI: () => options, - }, - }, 'npm-registry-fetch': { json: (path, opts) => { t.equal(path, '/-/whoami', 'calls whoami') @@ -81,9 +73,14 @@ test('throws ENEEDAUTH when response does not include a username', async (t) => }, }, }) + const npm = { + config: { + getCredentialsByURI: () => options, + }, + } try { - await getIdentity(options) + await getIdentity(npm, options) } catch (err) { t.equal(err.code, 'ENEEDAUTH', 'throws correct error code') } @@ -92,15 +89,15 @@ test('throws ENEEDAUTH when response does not include a username', async (t) => test('throws ENEEDAUTH when neither username nor token is configured', async (t) => { t.plan(1) const getIdentity = requireInject('../../../lib/utils/get-identity.js', { - '../../../lib/npm.js': { - config: { - getCredentialsByURI: () => ({}), - }, - }, }) + const npm = { + config: { + getCredentialsByURI: () => ({}), + }, + } try { - await getIdentity({ registry: 'https://registry.npmjs.org' }) + await getIdentity(npm, { registry: 'https://registry.npmjs.org' }) } catch (err) { t.equal(err.code, 'ENEEDAUTH', 'throws correct error code') } diff --git a/deps/npm/test/lib/utils/lifecycle-cmd.js b/deps/npm/test/lib/utils/lifecycle-cmd.js index 3928c1b26e..2f1f693f2d 100644 --- a/deps/npm/test/lib/utils/lifecycle-cmd.js +++ b/deps/npm/test/lib/utils/lifecycle-cmd.js @@ -1,13 +1,19 @@ const t = require('tap') -const lifecycleCmd = require('../../../lib/utils/lifecycle-cmd.js') +const LifecycleCmd = require('../../../lib/utils/lifecycle-cmd.js') +let runArgs = null const npm = { commands: { - 'run-script': (args, cb) => cb(null, 'called npm.commands.run'), + 'run-script': (args, cb) => { + runArgs = args + cb(null, 'called npm.commands.run') + }, }, } t.test('create a lifecycle command', t => { - const cmd = lifecycleCmd(npm, 'asdf') - cmd(['some', 'args'], (er, result) => { + const cmd = new LifecycleCmd(npm, 'test-stage') + t.match(cmd.usage, /test-stage/) + cmd.exec(['some', 'args'], (er, result) => { + t.same(runArgs, ['test-stage', 'some', 'args']) t.strictSame(result, 'called npm.commands.run') t.end() }) diff --git a/deps/npm/test/lib/utils/npm-usage.js b/deps/npm/test/lib/utils/npm-usage.js index 72504b90cb..dbbde947ce 100644 --- a/deps/npm/test/lib/utils/npm-usage.js +++ b/deps/npm/test/lib/utils/npm-usage.js @@ -1,127 +1,121 @@ const t = require('tap') -const deref = require('../../../lib/utils/deref-command.js') -const npm = { - argv: [], - deref, - config: { - _options: { - viewer: null, - long: false, - userconfig: '/some/config/file/.npmrc', - }, - get: k => { - if (npm.config._options[k] === undefined) - throw new Error('unknown config') - return npm.config._options[k] - }, - set: (k, v) => { - npm.config._options[k] = v - }, - }, - log: {}, - version: '{VERSION}', -} - const OUTPUT = [] const output = (...msg) => OUTPUT.push(msg) - -const { dirname } = require('path') -const basedir = dirname(dirname(dirname(__dirname))) -t.cleanSnapshot = str => str.split(basedir).join('{BASEDIR}') - .split(require('../../../package.json').version).join('{VERSION}') - const requireInject = require('require-inject') const usage = requireInject('../../../lib/utils/npm-usage.js', { - '../../../lib/npm.js': npm, '../../../lib/utils/output.js': output, }) +const npm = requireInject('../../../lib/npm.js') -t.test('basic usage', t => { - usage() - t.equal(OUTPUT.length, 1) - t.equal(OUTPUT[0].length, 1) - t.matchSnapshot(OUTPUT[0][0]) - OUTPUT.length = 0 - t.end() -}) - -t.test('with browser', t => { - npm.config.set('viewer', 'browser') - usage() - t.equal(OUTPUT.length, 1) - t.equal(OUTPUT[0].length, 1) - t.matchSnapshot(OUTPUT[0][0]) - OUTPUT.length = 0 - npm.config.set('viewer', null) - t.end() -}) +t.test('usage', t => { + t.afterEach((cb) => { + npm.config.set('viewer', null) + npm.config.set('long', false) + npm.config.set('userconfig', '/some/config/file/.npmrc') + cb() + }) + const { dirname } = require('path') + const basedir = dirname(dirname(dirname(__dirname))) + t.cleanSnapshot = str => str.split(basedir).join('{BASEDIR}') + .split(require('../../../package.json').version).join('{VERSION}') -t.test('with long', t => { - npm.config.set('long', true) - usage() - t.equal(OUTPUT.length, 1) - t.equal(OUTPUT[0].length, 1) - t.matchSnapshot(OUTPUT[0][0]) - OUTPUT.length = 0 - npm.config.set('long', false) - t.end() -}) + npm.load(err => { + if (err) + throw err -t.test('did you mean?', t => { - npm.argv.push('unistnall') - usage() - t.equal(OUTPUT.length, 2) - t.equal(OUTPUT[0].length, 1) - t.equal(OUTPUT[1].length, 1) - t.matchSnapshot(OUTPUT[0][0]) - t.matchSnapshot(OUTPUT[1][0]) - OUTPUT.length = 0 - npm.argv.length = 0 - t.end() -}) + npm.config.set('viewer', null) + npm.config.set('long', false) + npm.config.set('userconfig', '/some/config/file/.npmrc') -t.test('did you mean?', t => { - npm.argv.push('unistnall') - const { exitCode } = process - t.teardown(() => { - if (t.passing()) - process.exitCode = exitCode - }) - // make sure it fails when invalid - usage(false) - t.equal(process.exitCode, 1) - OUTPUT.length = 0 - npm.argv.length = 0 - t.end() -}) + t.test('basic usage', t => { + usage(npm) + t.equal(OUTPUT.length, 1) + t.equal(OUTPUT[0].length, 1) + t.matchSnapshot(OUTPUT[0][0]) + OUTPUT.length = 0 + t.end() + }) -t.test('set process.stdout.columns', t => { - const { columns } = process.stdout - t.teardown(() => { - Object.defineProperty(process.stdout, 'columns', { - value: columns, - enumerable: true, - configurable: true, - writable: true, + t.test('with browser', t => { + npm.config.set('viewer', 'browser') + usage(npm) + t.equal(OUTPUT.length, 1) + t.equal(OUTPUT[0].length, 1) + t.matchSnapshot(OUTPUT[0][0]) + OUTPUT.length = 0 + npm.config.set('viewer', null) + t.end() }) - }) - const cases = [0, 90] - for (const cols of cases) { - t.test(`columns=${cols}`, t => { - Object.defineProperty(process.stdout, 'columns', { - value: cols, - enumerable: true, - configurable: true, - writable: true, - }) - usage() + + t.test('with long', t => { + npm.config.set('long', true) + usage(npm) t.equal(OUTPUT.length, 1) t.equal(OUTPUT[0].length, 1) t.matchSnapshot(OUTPUT[0][0]) OUTPUT.length = 0 + npm.config.set('long', false) + t.end() + }) + + t.test('did you mean?', t => { + npm.argv.push('unistnall') + usage(npm) + t.equal(OUTPUT.length, 2) + t.equal(OUTPUT[0].length, 1) + t.equal(OUTPUT[1].length, 1) + t.matchSnapshot(OUTPUT[0][0]) + t.matchSnapshot(OUTPUT[1][0]) + OUTPUT.length = 0 + npm.argv.length = 0 t.end() }) - } - t.end() + + t.test('did you mean?', t => { + npm.argv.push('unistnall') + const { exitCode } = process + t.teardown(() => { + if (t.passing()) + process.exitCode = exitCode + }) + // make sure it fails when invalid + usage(npm, false) + t.equal(process.exitCode, 1) + OUTPUT.length = 0 + npm.argv.length = 0 + t.end() + }) + + t.test('set process.stdout.columns', t => { + const { columns } = process.stdout + t.teardown(() => { + Object.defineProperty(process.stdout, 'columns', { + value: columns, + enumerable: true, + configurable: true, + writable: true, + }) + }) + const cases = [0, 90] + for (const cols of cases) { + t.test(`columns=${cols}`, t => { + Object.defineProperty(process.stdout, 'columns', { + value: cols, + enumerable: true, + configurable: true, + writable: true, + }) + usage(npm) + t.equal(OUTPUT.length, 1) + t.equal(OUTPUT[0].length, 1) + t.matchSnapshot(OUTPUT[0][0]) + OUTPUT.length = 0 + t.end() + }) + } + t.end() + }) + t.end() + }) }) diff --git a/deps/npm/test/lib/utils/open-url.js b/deps/npm/test/lib/utils/open-url.js index ce1783dadc..e8ab8f15a1 100644 --- a/deps/npm/test/lib/utils/open-url.js +++ b/deps/npm/test/lib/utils/open-url.js @@ -27,59 +27,49 @@ const opener = (url, opts, cb) => { } const openUrl = requireInject('../../../lib/utils/open-url.js', { - '../../../lib/npm.js': npm, '../../../lib/utils/output.js': output, opener, }) -test('opens a url', (t) => { +test('opens a url', async (t) => { t.teardown(() => { openerUrl = null openerOpts = null OUTPUT.length = 0 }) - openUrl('https://www.npmjs.com', 'npm home', (err) => { - if (err) - throw err - - t.equal(openerUrl, 'https://www.npmjs.com', 'opened the given url') - t.same(openerOpts, { command: null }, 'passed command as null (the default)') - t.same(OUTPUT, [], 'printed no output') - t.done() - }) + await openUrl(npm, 'https://www.npmjs.com', 'npm home') + t.equal(openerUrl, 'https://www.npmjs.com', 'opened the given url') + t.same(openerOpts, { command: null }, 'passed command as null (the default)') + t.same(OUTPUT, [], 'printed no output') }) -test('returns error for non-https and non-file url', (t) => { +test('returns error for non-https and non-file url', async (t) => { t.teardown(() => { openerUrl = null openerOpts = null OUTPUT.length = 0 }) - openUrl('ftp://www.npmjs.com', 'npm home', (err) => { - t.match(err, /Invalid URL/, 'got the correct error') - t.equal(openerUrl, null, 'did not open') - t.same(openerOpts, null, 'did not open') - t.same(OUTPUT, [], 'printed no output') - t.done() - }) + t.rejects(openUrl(npm, 'ftp://www.npmjs.com', 'npm home'), /Invalid URL/, 'got the correct error') + t.equal(openerUrl, null, 'did not open') + t.same(openerOpts, null, 'did not open') + t.same(OUTPUT, [], 'printed no output') + t.done() }) -test('returns error for non-parseable url', (t) => { +test('returns error for non-parseable url', async (t) => { t.teardown(() => { openerUrl = null openerOpts = null OUTPUT.length = 0 }) - openUrl('git+ssh://user@host:repo.git', 'npm home', (err) => { - t.match(err, /Invalid URL/, 'got the correct error') - t.equal(openerUrl, null, 'did not open') - t.same(openerOpts, null, 'did not open') - t.same(OUTPUT, [], 'printed no output') - t.done() - }) + t.rejects(openUrl(npm, 'git+ssh://user@host:repo.git', 'npm home'), /Invalid URL/, 'got the correct error') + t.equal(openerUrl, null, 'did not open') + t.same(openerOpts, null, 'did not open') + t.same(OUTPUT, [], 'printed no output') + t.done() }) -test('opens a url with the given browser', (t) => { +test('opens a url with the given browser', async (t) => { npm.config.set('browser', 'chrome') t.teardown(() => { openerUrl = null @@ -87,18 +77,14 @@ test('opens a url with the given browser', (t) => { OUTPUT.length = 0 npm.config.set('browser', true) }) - openUrl('https://www.npmjs.com', 'npm home', (err) => { - if (err) - throw err - - t.equal(openerUrl, 'https://www.npmjs.com', 'opened the given url') - t.same(openerOpts, { command: 'chrome' }, 'passed the given browser as command') - t.same(OUTPUT, [], 'printed no output') - t.done() - }) + await openUrl(npm, 'https://www.npmjs.com', 'npm home') + t.equal(openerUrl, 'https://www.npmjs.com', 'opened the given url') + t.same(openerOpts, { command: 'chrome' }, 'passed the given browser as command') + t.same(OUTPUT, [], 'printed no output') + t.done() }) -test('prints where to go when browser is disabled', (t) => { +test('prints where to go when browser is disabled', async (t) => { npm.config.set('browser', false) t.teardown(() => { openerUrl = null @@ -106,20 +92,16 @@ test('prints where to go when browser is disabled', (t) => { OUTPUT.length = 0 npm.config.set('browser', true) }) - openUrl('https://www.npmjs.com', 'npm home', (err) => { - if (err) - throw err - - t.equal(openerUrl, null, 'did not open') - t.same(openerOpts, null, 'did not open') - t.equal(OUTPUT.length, 1, 'got one logged message') - t.equal(OUTPUT[0].length, 1, 'logged message had one value') - t.matchSnapshot(OUTPUT[0][0], 'printed expected message') - t.done() - }) + await openUrl(npm, 'https://www.npmjs.com', 'npm home') + t.equal(openerUrl, null, 'did not open') + t.same(openerOpts, null, 'did not open') + t.equal(OUTPUT.length, 1, 'got one logged message') + t.equal(OUTPUT[0].length, 1, 'logged message had one value') + t.matchSnapshot(OUTPUT[0][0], 'printed expected message') + t.done() }) -test('prints where to go when browser is disabled and json is enabled', (t) => { +test('prints where to go when browser is disabled and json is enabled', async (t) => { npm.config.set('browser', false) npm.config.set('json', true) t.teardown(() => { @@ -129,20 +111,16 @@ test('prints where to go when browser is disabled and json is enabled', (t) => { npm.config.set('browser', true) npm.config.set('json', false) }) - openUrl('https://www.npmjs.com', 'npm home', (err) => { - if (err) - throw err - - t.equal(openerUrl, null, 'did not open') - t.same(openerOpts, null, 'did not open') - t.equal(OUTPUT.length, 1, 'got one logged message') - t.equal(OUTPUT[0].length, 1, 'logged message had one value') - t.matchSnapshot(OUTPUT[0][0], 'printed expected message') - t.done() - }) + await openUrl(npm, 'https://www.npmjs.com', 'npm home') + t.equal(openerUrl, null, 'did not open') + t.same(openerOpts, null, 'did not open') + t.equal(OUTPUT.length, 1, 'got one logged message') + t.equal(OUTPUT[0].length, 1, 'logged message had one value') + t.matchSnapshot(OUTPUT[0][0], 'printed expected message') + t.done() }) -test('prints where to go when given browser does not exist', (t) => { +test('prints where to go when given browser does not exist', async (t) => { npm.config.set('browser', 'firefox') openerResult = Object.assign(new Error('failed'), { code: 'ENOENT' }) t.teardown(() => { @@ -151,15 +129,24 @@ test('prints where to go when given browser does not exist', (t) => { OUTPUT.length = 0 npm.config.set('browser', true) }) - openUrl('https://www.npmjs.com', 'npm home', (err) => { - if (err) - throw err + await openUrl(npm, 'https://www.npmjs.com', 'npm home') + t.equal(openerUrl, 'https://www.npmjs.com', 'tried to open the correct url') + t.same(openerOpts, { command: 'firefox' }, 'tried to use the correct browser') + t.equal(OUTPUT.length, 1, 'got one logged message') + t.equal(OUTPUT[0].length, 1, 'logged message had one value') + t.matchSnapshot(OUTPUT[0][0], 'printed expected message') + t.done() +}) - t.equal(openerUrl, 'https://www.npmjs.com', 'tried to open the correct url') - t.same(openerOpts, { command: 'firefox' }, 'tried to use the correct browser') - t.equal(OUTPUT.length, 1, 'got one logged message') - t.equal(OUTPUT[0].length, 1, 'logged message had one value') - t.matchSnapshot(OUTPUT[0][0], 'printed expected message') - t.done() +test('handles unknown opener error', async (t) => { + npm.config.set('browser', 'firefox') + openerResult = Object.assign(new Error('failed'), { code: 'ENOBRIAN' }) + t.teardown(() => { + openerUrl = null + openerOpts = null + OUTPUT.length = 0 + npm.config.set('browser', true) }) + t.rejects(openUrl(npm, 'https://www.npmjs.com', 'npm home'), 'failed', 'got the correct error') + t.done() }) diff --git a/deps/npm/test/lib/utils/read-local-package.js b/deps/npm/test/lib/utils/read-local-package.js index 33a408eb53..9ae21f7d62 100644 --- a/deps/npm/test/lib/utils/read-local-package.js +++ b/deps/npm/test/lib/utils/read-local-package.js @@ -10,11 +10,10 @@ const _flatOptions = { }, } -const readLocalPackageName = requireInject('../../../lib/utils/read-local-package.js', { - '../../../lib/npm.js': { - flatOptions: _flatOptions, - }, -}) +const readLocalPackageName = requireInject('../../../lib/utils/read-local-package.js') +const npm = { + flatOptions: _flatOptions, +} test('read local package.json', async (t) => { prefix = t.testdir({ @@ -23,7 +22,7 @@ test('read local package.json', async (t) => { version: '1.0.0', }), }) - const packageName = await readLocalPackageName() + const packageName = await readLocalPackageName(npm) t.equal( packageName, 'my-local-package', @@ -38,7 +37,7 @@ test('read local scoped-package.json', async (t) => { version: '1.0.0', }), }) - const packageName = await readLocalPackageName() + const packageName = await readLocalPackageName(npm) t.equal( packageName, '@my-scope/my-local-package', @@ -49,7 +48,7 @@ test('read local scoped-package.json', async (t) => { test('read using --global', async (t) => { prefix = t.testdir({}) _flatOptions.global = true - const packageName = await readLocalPackageName() + const packageName = await readLocalPackageName(npm) t.equal( packageName, undefined, diff --git a/deps/npm/test/lib/utils/reify-finish.js b/deps/npm/test/lib/utils/reify-finish.js index 39277f21a0..7ff5146a6b 100644 --- a/deps/npm/test/lib/utils/reify-finish.js +++ b/deps/npm/test/lib/utils/reify-finish.js @@ -32,13 +32,12 @@ const fs = { const reifyFinish = requireInject('../../../lib/utils/reify-finish.js', { fs, - '../../../lib/npm.js': npm, '../../../lib/utils/reify-output.js': reifyOutput, }) t.test('should not write if not global', async t => { expectWrite = false - await reifyFinish({ + await reifyFinish(npm, { options: { global: false }, actualTree: {}, }) @@ -46,7 +45,7 @@ t.test('should not write if not global', async t => { t.test('should not write if no global npm module', async t => { expectWrite = false - await reifyFinish({ + await reifyFinish(npm, { options: { global: true }, actualTree: { inventory: new Map(), @@ -56,7 +55,7 @@ t.test('should not write if no global npm module', async t => { t.test('should not write if builtin conf had load error', async t => { expectWrite = false - await reifyFinish({ + await reifyFinish(npm, { options: { global: true }, actualTree: { inventory: new Map([['node_modules/npm', {}]]), @@ -68,7 +67,7 @@ t.test('should write if everything above passes', async t => { expectWrite = true delete builtinConfMock.loadError const path = t.testdir() - await reifyFinish({ + await reifyFinish(npm, { options: { global: true }, actualTree: { inventory: new Map([['node_modules/npm', {path}]]), diff --git a/deps/npm/test/lib/utils/reify-output.js b/deps/npm/test/lib/utils/reify-output.js index f88f072e1e..e41eabcb89 100644 --- a/deps/npm/test/lib/utils/reify-output.js +++ b/deps/npm/test/lib/utils/reify-output.js @@ -9,7 +9,7 @@ t.cleanSnapshot = str => str.replace(/in [0-9]+m?s/g, 'in {TIME}') const settings = { fund: true, } -const npmock = { +const npm = { started: Date.now(), flatOptions: settings, } @@ -17,7 +17,6 @@ const getReifyOutput = tester => requireInject( '../../../lib/utils/reify-output.js', { - '../../../lib/npm.js': npmock, '../../../lib/utils/output.js': tester, } ) @@ -32,7 +31,7 @@ t.test('missing info', (t) => { ) ) - reifyOutput({ + reifyOutput(npm, { actualTree: { children: [], }, @@ -52,7 +51,7 @@ t.test('even more missing info', t => { ) ) - reifyOutput({ + reifyOutput(npm, { actualTree: { children: [], }, @@ -73,7 +72,7 @@ t.test('single package', (t) => { } ) - reifyOutput({ + reifyOutput(npm, { // a report with an error is the same as no report at all, if // the command is not 'audit' auditReport: { @@ -118,7 +117,7 @@ t.test('no message when funding config is false', (t) => { } ) - reifyOutput({ + reifyOutput(npm, { actualTree: { name: 'foo', package: { @@ -160,7 +159,7 @@ t.test('print appropriate message for many packages', (t) => { } ) - reifyOutput({ + reifyOutput(npm, { actualTree: { name: 'foo', package: { @@ -212,7 +211,7 @@ t.test('no output when silent', t => { }) t.teardown(() => log.level = 'warn') log.level = 'silent' - reifyOutput({ + reifyOutput(npm, { actualTree: { inventory: { size: 999 }, children: [] }, auditReport: { toJSON: () => { @@ -243,7 +242,7 @@ t.test('packages changed message', t => { // return a test function that builds up the mock and snapshots output const testCase = (t, added, removed, changed, audited, json, command) => { settings.json = json - npmock.command = command + npm.command = command const mock = { actualTree: { inventory: { size: audited, has: () => true }, @@ -276,7 +275,7 @@ t.test('packages changed message', t => { mock.diff.children.push({ action: 'CHANGE', actual, ideal }) } output.length = 0 - reifyOutput(mock) + reifyOutput(npm, mock) t.matchSnapshot(output.join('\n'), JSON.stringify({ added, removed, @@ -316,7 +315,7 @@ t.test('added packages should be looked up within returned tree', t => { out => t.matchSnapshot(out) ) - reifyOutput({ + reifyOutput(npm, { actualTree: { name: 'foo', inventory: { @@ -337,7 +336,7 @@ t.test('added packages should be looked up within returned tree', t => { out => t.matchSnapshot(out) ) - reifyOutput({ + reifyOutput(npm, { actualTree: { name: 'foo', inventory: { diff --git a/deps/npm/test/lib/version.js b/deps/npm/test/lib/version.js index a69953bb8a..e0e07f5172 100644 --- a/deps/npm/test/lib/version.js +++ b/deps/npm/test/lib/version.js @@ -14,7 +14,6 @@ const npm = { } const mocks = { libnpmversion: noop, - '../../lib/npm.js': npm, '../../lib/utils/output.js': (...msg) => { for (const m of msg) result.push(m) @@ -22,7 +21,8 @@ const mocks = { '../../lib/utils/usage.js': () => 'usage instructions', } -const version = requireInject('../../lib/version.js', mocks) +const Version = requireInject('../../lib/version.js', mocks) +const version = new Version(npm) const _processVersions = process.versions t.afterEach(cb => { @@ -43,7 +43,7 @@ t.test('no args', t => { npm.prefix = prefix Object.defineProperty(process, 'versions', { value: { node: '1.0.0' } }) - version([], err => { + version.exec([], err => { if (err) throw err @@ -62,7 +62,7 @@ t.test('no args', t => { }) t.test('too many args', t => { - version(['foo', 'bar'], err => { + version.exec(['foo', 'bar'], err => { t.match( err, 'usage instructions', @@ -74,10 +74,8 @@ t.test('too many args', t => { }) t.test('completion', async t => { - const { completion } = version - const testComp = async (argv, expect) => { - const res = await completion({ conf: { argv: { remain: argv } } }) + const res = await version.completion({ conf: { argv: { remain: argv } } }) t.strictSame(res, expect, argv.join(' ')) } @@ -100,7 +98,7 @@ t.test('failure reading package.json', t => { const prefix = t.testdir({}) npm.prefix = prefix - version([], err => { + version.exec([], err => { if (err) throw err @@ -123,7 +121,7 @@ t.test('--json option', t => { npm.prefix = prefix Object.defineProperty(process, 'versions', { value: {} }) - version([], err => { + version.exec([], err => { if (err) throw err t.deepEqual( @@ -136,7 +134,7 @@ t.test('--json option', t => { }) t.test('with one arg', t => { - const version = requireInject('../../lib/version.js', { + const Version = requireInject('../../lib/version.js', { ...mocks, libnpmversion: (arg, opts) => { t.equal(arg, 'major', 'should forward expected value') @@ -152,8 +150,9 @@ t.test('with one arg', t => { return '4.0.0' }, }) + const version = new Version(npm) - version(['major'], err => { + version.exec(['major'], err => { if (err) throw err t.same(result, ['v4.0.0'], 'outputs the new version prefixed by the tagVersionPrefix') diff --git a/deps/npm/test/lib/view.js b/deps/npm/test/lib/view.js index 9419ab7ec8..1363a5b9f9 100644 --- a/deps/npm/test/lib/view.js +++ b/deps/npm/test/lib/view.js @@ -238,98 +238,98 @@ const packument = (nv, opts) => { t.beforeEach(cleanLogs) t.test('should log package info', t => { - const view = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - flatOptions: { - global: false, - }, - }, + const View = requireInject('../../lib/view.js', { pacote: { packument, }, }) - - const viewJson = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - flatOptions: { - json: true, - }, + const view = new View({ + flatOptions: { + global: false, }, + }) + + const ViewJson = requireInject('../../lib/view.js', { pacote: { packument, }, }) - - const viewUnicode = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - flatOptions: { - global: false, - unicode: true, - }, + const viewJson = new ViewJson({ + flatOptions: { + json: true, }, + }) + + const ViewUnicode = requireInject('../../lib/view.js', { pacote: { packument, }, }) + const viewUnicode = new ViewUnicode({ + flatOptions: { + global: false, + unicode: true, + }, + }) t.test('package with license, bugs, repository and other fields', t => { - view(['green@1.0.0'], () => { + view.exec(['green@1.0.0'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('package with more than 25 deps', t => { - view(['black@1.0.0'], () => { + view.exec(['black@1.0.0'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('package with maintainers info as object', t => { - view(['pink@1.0.0'], () => { + view.exec(['pink@1.0.0'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('package with homepage', t => { - view(['orange@1.0.0'], () => { + view.exec(['orange@1.0.0'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('package with no versions', t => { - view(['brown'], () => { + view.exec(['brown'], () => { t.equals(logs, '', 'no info to display') t.end() }) }) t.test('package with no repo or homepage', t => { - view(['blue@1.0.0'], () => { + view.exec(['blue@1.0.0'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('package with no modified time', t => { - viewUnicode(['cyan@1.0.0'], () => { + viewUnicode.exec(['cyan@1.0.0'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('package with --json and semver range', t => { - viewJson(['cyan@^1.0.0'], () => { + viewJson.exec(['cyan@^1.0.0'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('package with --json and no versions', t => { - viewJson(['brown'], () => { + viewJson.exec(['brown'], () => { t.equals(logs, '', 'no info to display') t.end() }) @@ -346,28 +346,28 @@ t.test('should log info of package in current working dir', t => { }, null, 2), }) - const view = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - prefix: testDir, - flatOptions: { - defaultTag: '1.0.0', - global: false, - }, - }, + const View = requireInject('../../lib/view.js', { pacote: { packument, }, }) + const view = new View({ + prefix: testDir, + flatOptions: { + defaultTag: '1.0.0', + global: false, + }, + }) t.test('specific version', t => { - view(['.@1.0.0'], () => { + view.exec(['.@1.0.0'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('non-specific version', t => { - view(['.'], () => { + view.exec(['.'], () => { t.matchSnapshot(logs) t.end() }) @@ -377,87 +377,87 @@ t.test('should log info of package in current working dir', t => { }) t.test('should log info by field name', t => { - const viewJson = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - flatOptions: { - json: true, - global: false, - }, - }, + const ViewJson = requireInject('../../lib/view.js', { pacote: { packument, }, }) - - const view = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - flatOptions: { - global: false, - }, + const viewJson = new ViewJson({ + flatOptions: { + json: true, + global: false, }, + }) + + const View = requireInject('../../lib/view.js', { pacote: { packument, }, }) + const view = new View({ + flatOptions: { + global: false, + }, + }) t.test('readme', t => { - view(['yellow@1.0.0', 'readme'], () => { + view.exec(['yellow@1.0.0', 'readme'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('several fields', t => { - viewJson(['yellow@1.0.0', 'name', 'version', 'foo[bar]'], () => { + viewJson.exec(['yellow@1.0.0', 'name', 'version', 'foo[bar]'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('several fields with several versions', t => { - view(['yellow@1.x.x', 'author'], () => { + view.exec(['yellow@1.x.x', 'author'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('nested field with brackets', t => { - viewJson(['orange@1.0.0', 'dist[shasum]'], () => { + viewJson.exec(['orange@1.0.0', 'dist[shasum]'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('maintainers with email', t => { - viewJson(['yellow@1.0.0', 'maintainers', 'name'], () => { + viewJson.exec(['yellow@1.0.0', 'maintainers', 'name'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('maintainers with url', t => { - viewJson(['pink@1.0.0', 'maintainers'], () => { + viewJson.exec(['pink@1.0.0', 'maintainers'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('unknown nested field ', t => { - view(['yellow@1.0.0', 'dist.foobar'], () => { + view.exec(['yellow@1.0.0', 'dist.foobar'], () => { t.equals(logs, '', 'no info to display') t.end() }) }) t.test('array field - 1 element', t => { - view(['purple@1.0.0', 'maintainers.name'], () => { + view.exec(['purple@1.0.0', 'maintainers.name'], () => { t.matchSnapshot(logs) t.end() }) }) t.test('array field - 2 elements', t => { - view(['yellow@1.x.x', 'maintainers.name'], () => { + view.exec(['yellow@1.x.x', 'maintainers.name'], () => { t.matchSnapshot(logs) t.end() }) @@ -467,14 +467,13 @@ t.test('should log info by field name', t => { }) t.test('throw error if global mode', (t) => { - const view = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - flatOptions: { - global: true, - }, + const View = requireInject('../../lib/view.js') + const view = new View({ + flatOptions: { + global: true, }, }) - view([], (err) => { + view.exec([], (err) => { t.equals(err.message, 'Cannot use view command in global mode.') t.end() }) @@ -483,15 +482,14 @@ t.test('throw error if global mode', (t) => { t.test('throw ENOENT error if package.json misisng', (t) => { const testDir = t.testdir({}) - const view = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - prefix: testDir, - flatOptions: { - global: false, - }, + const View = requireInject('../../lib/view.js') + const view = new View({ + prefix: testDir, + flatOptions: { + global: false, }, }) - view([], (err) => { + view.exec([], (err) => { t.match(err, { code: 'ENOENT' }) t.end() }) @@ -502,15 +500,14 @@ t.test('throw EJSONPARSE error if package.json not json', (t) => { 'package.json': 'not json, nope, not even a little bit!', }) - const view = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - prefix: testDir, - flatOptions: { - global: false, - }, + const View = requireInject('../../lib/view.js') + const view = new View({ + prefix: testDir, + flatOptions: { + global: false, }, }) - view([], (err) => { + view.exec([], (err) => { t.match(err, { code: 'EJSONPARSE' }) t.end() }) @@ -521,50 +518,49 @@ t.test('throw error if package.json has no name', (t) => { 'package.json': '{}', }) - const view = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - prefix: testDir, - flatOptions: { - global: false, - }, + const View = requireInject('../../lib/view.js') + const view = new View({ + prefix: testDir, + flatOptions: { + global: false, }, }) - view([], (err) => { + view.exec([], (err) => { t.equals(err.message, 'Invalid package.json, no "name" field') t.end() }) }) t.test('throws when unpublished', (t) => { - const view = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - flatOptions: { - defaultTag: '1.0.1', - global: false, - }, - }, + const View = requireInject('../../lib/view.js', { pacote: { packument, }, }) - view(['red'], (err) => { + const view = new View({ + flatOptions: { + defaultTag: '1.0.1', + global: false, + }, + }) + view.exec(['red'], (err) => { t.equals(err.code, 'E404') t.end() }) }) t.test('completion', async t => { - const view = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - flatOptions: { - defaultTag: '1.0.1', - global: false, - }, - }, + const View = requireInject('../../lib/view.js', { pacote: { packument, }, }) + const view = new View({ + flatOptions: { + defaultTag: '1.0.1', + global: false, + }, + }) const res = await view.completion({ conf: { argv: { remain: ['npm', 'view', 'green@1.0.0'] } }, }) @@ -573,11 +569,10 @@ t.test('completion', async t => { }) t.test('no registry completion', async t => { - const view = requireInject('../../lib/view.js', { - '../../lib/npm.js': { - flatOptions: { - defaultTag: '1.0.1', - }, + const View = requireInject('../../lib/view.js') + const view = new View({ + flatOptions: { + defaultTag: '1.0.1', }, }) const res = await view.completion({conf: { argv: { remain: ['npm', 'view'] } } }) diff --git a/deps/npm/test/lib/whoami.js b/deps/npm/test/lib/whoami.js index d54814db36..3d9618ffa7 100644 --- a/deps/npm/test/lib/whoami.js +++ b/deps/npm/test/lib/whoami.js @@ -3,15 +3,15 @@ const requireInject = require('require-inject') test('whoami', (t) => { t.plan(3) - const whoami = requireInject('../../lib/whoami.js', { + const Whoami = requireInject('../../lib/whoami.js', { '../../lib/utils/get-identity.js': () => Promise.resolve('foo'), - '../../lib/npm.js': { flatOptions: {} }, '../../lib/utils/output.js': (output) => { t.equal(output, 'foo', 'should output the username') }, }) + const whoami = new Whoami({ flatOptions: {} }) - whoami([], (err) => { + whoami.exec([], (err) => { t.ifError(err, 'npm whoami') t.ok('should successfully print username') }) @@ -19,15 +19,15 @@ test('whoami', (t) => { test('whoami json', (t) => { t.plan(3) - const whoami = requireInject('../../lib/whoami.js', { + const Whoami = requireInject('../../lib/whoami.js', { '../../lib/utils/get-identity.js': () => Promise.resolve('foo'), - '../../lib/npm.js': { flatOptions: { json: true } }, '../../lib/utils/output.js': (output) => { t.equal(output, '"foo"', 'should output the username as json') }, }) + const whoami = new Whoami({ flatOptions: { json: true } }) - whoami([], (err) => { + whoami.exec([], (err) => { t.ifError(err, 'npm whoami') t.ok('should successfully print username as json') }) |