diff options
Diffstat (limited to 'deps/npm/test')
-rw-r--r-- | deps/npm/test/fixtures/mock-npm.js | 9 | ||||
-rw-r--r-- | deps/npm/test/lib/cache.js | 279 | ||||
-rw-r--r-- | deps/npm/test/lib/cli.js | 26 | ||||
-rw-r--r-- | deps/npm/test/lib/find-dupes.js | 36 | ||||
-rw-r--r-- | deps/npm/test/lib/get.js | 26 | ||||
-rw-r--r-- | deps/npm/test/lib/load-all.js | 22 | ||||
-rw-r--r-- | deps/npm/test/lib/prefix.js | 26 | ||||
-rw-r--r-- | deps/npm/test/lib/prune.js | 20 | ||||
-rw-r--r-- | deps/npm/test/lib/restart.js | 48 | ||||
-rw-r--r-- | deps/npm/test/lib/root.js | 26 | ||||
-rw-r--r-- | deps/npm/test/lib/set.js | 27 | ||||
-rw-r--r-- | deps/npm/test/lib/start.js | 48 | ||||
-rw-r--r-- | deps/npm/test/lib/stop.js | 48 | ||||
-rw-r--r-- | deps/npm/test/lib/test.js | 60 | ||||
-rw-r--r-- | deps/npm/test/lib/utils/completion/installed-deep.js | 4 | ||||
-rw-r--r-- | deps/npm/test/lib/utils/error-message.js | 6 | ||||
-rw-r--r-- | deps/npm/test/lib/utils/tar.js | 4 | ||||
-rw-r--r-- | deps/npm/test/lib/whoami.js | 50 |
18 files changed, 561 insertions, 204 deletions
diff --git a/deps/npm/test/fixtures/mock-npm.js b/deps/npm/test/fixtures/mock-npm.js index e3be10b4b9a..3faf8d5cf4f 100644 --- a/deps/npm/test/fixtures/mock-npm.js +++ b/deps/npm/test/fixtures/mock-npm.js @@ -9,6 +9,10 @@ for (const level in npmlog.levels) const { title, execPath } = process const RealMockNpm = (t, otherMocks = {}) => { + t.afterEach(() => { + outputs.length = 0 + logs.length = 0 + }) t.teardown(() => { npm.perfStop() npmlog.record.length = 0 @@ -22,6 +26,9 @@ const RealMockNpm = (t, otherMocks = {}) => { }) const logs = [] const outputs = [] + const joinedOutput = () => { + return outputs.map(o => o.join(' ')).join('\n') + } const npm = t.mock('../../lib/npm.js', otherMocks) const command = async (command, args = []) => { return new Promise((resolve, reject) => { @@ -43,7 +50,7 @@ const RealMockNpm = (t, otherMocks = {}) => { } } npm.output = (...msg) => outputs.push(msg) - return { npm, logs, outputs, command } + return { npm, logs, outputs, command, joinedOutput } } const realConfig = require('../../lib/utils/config') diff --git a/deps/npm/test/lib/cache.js b/deps/npm/test/lib/cache.js index d3d6f5b8845..c6405303202 100644 --- a/deps/npm/test/lib/cache.js +++ b/deps/npm/test/lib/cache.js @@ -1,6 +1,7 @@ const t = require('tap') const { fake: mockNpm } = require('../fixtures/mock-npm.js') const path = require('path') +const npa = require('npm-package-arg') const usageUtil = () => 'usage instructions' @@ -34,16 +35,104 @@ const pacote = { }, } +let cacacheEntries = {} +let cacacheContent = {} + +const setupCacacheFixture = () => { + cacacheEntries = {} + cacacheContent = {} + const pkgs = [ + ['webpack@4.44.1', 'https://registry.npmjs.org', true], + ['npm@1.2.0', 'https://registry.npmjs.org', true], + ['webpack@4.47.0', 'https://registry.npmjs.org', true], + ['foo@1.2.3-beta', 'https://registry.npmjs.org', true], + ['ape-ecs@2.1.7', 'https://registry.npmjs.org', true], + ['@fritzy/staydown@3.1.1', 'https://registry.npmjs.org', true], + ['@gar/npm-expansion@2.1.0', 'https://registry.npmjs.org', true], + ['@gar/npm-expansion@3.0.0-beta', 'https://registry.npmjs.org', true], + ['extemporaneously@44.2.2', 'https://somerepo.github.org', false], + ['corrupted@3.1.0', 'https://registry.npmjs.org', true], + ['missing-dist@23.0.0', 'https://registry.npmjs.org', true], + ['missing-version@16.2.0', 'https://registry.npmjs.org', true], + ] + pkgs.forEach(pkg => addCacachePkg(...pkg)) + // corrupt the packument + cacacheContent[ + [cacacheEntries['make-fetch-happen:request-cache:https://registry.npmjs.org/corrupted'].integrity] + ].data = Buffer.from('<>>>}"') + // nuke the version dist + cacacheContent[ + [cacacheEntries['make-fetch-happen:request-cache:https://registry.npmjs.org/missing-dist'].integrity] + ].data = Buffer.from(JSON.stringify({ versions: { '23.0.0': {} } })) + // make the version a non-object + cacacheContent[ + [cacacheEntries['make-fetch-happen:request-cache:https://registry.npmjs.org/missing-version'].integrity] + ].data = Buffer.from(JSON.stringify({ versions: 'hello' })) +} + +const packuments = {} + +let contentId = 0 const cacacheVerifyStats = { keptSize: 100, verifiedContent: 1, totalEntries: 1, runTime: { total: 2000 }, } + +const addCacacheKey = (key, content) => { + contentId++ + cacacheEntries[key] = { integrity: `${contentId}` } + cacacheContent[`${contentId}`] = {} +} +const addCacachePkg = (spec, registry, publicURL) => { + const parts = npa(spec) + const ver = parts.rawSpec || '1.0.0' + let url = `${registry}/${parts.name}/-/${parts.name}-${ver}.tgz` + if (!publicURL) + url = `${registry}/aabbcc/${contentId}` + const key = `make-fetch-happen:request-cache:${url}` + const pkey = `make-fetch-happen:request-cache:${registry}/${parts.escapedName}` + if (!packuments[parts.escapedName]) { + packuments[parts.escapedName] = { + versions: {}, + } + addCacacheKey(pkey) + } + packuments[parts.escapedName].versions[ver] = { + dist: { + tarball: url, + }, + } + addCacacheKey(key) + cacacheContent[cacacheEntries[pkey].integrity] = { + data: Buffer.from(JSON.stringify(packuments[parts.escapedName])), + } +} + const cacache = { verify: (path) => { return cacacheVerifyStats }, + get: (path, key) => { + if (cacacheEntries[key] === undefined + || cacacheContent[cacacheEntries[key].integrity] === undefined) + throw new Error() + return cacacheContent[cacacheEntries[key].integrity] + }, + rm: { + entry: (path, key) => { + if (cacacheEntries[key] === undefined) + throw new Error() + delete cacacheEntries[key] + }, + content: (path, sha) => { + delete cacacheContent[sha] + }, + }, + ls: (path) => { + return cacacheEntries + }, } const Cache = t.mock('../../lib/cache.js', { @@ -61,6 +150,11 @@ const npm = mockNpm({ output: (msg) => { outputOutput.push(msg) }, + log: { + warn: (...args) => { + logOutput.push(['warn', ...args]) + }, + }, }) const cache = new Cache(npm) @@ -94,13 +188,6 @@ t.test('cache clean (force)', t => { }) }) -t.test('cache clean with arg', t => { - cache.exec(['rm', 'pkg'], err => { - t.match(err.message, 'does not accept arguments', 'should throw error') - t.end() - }) -}) - t.test('cache add no arg', t => { t.teardown(() => { logOutput = [] @@ -136,7 +223,7 @@ t.test('cache add pkg only', t => { t.test('cache add multiple pkgs', t => { t.teardown(() => { - logOutput = [] + outputOutput = [] tarballStreamSpec = '' tarballStreamOpts = {} }) @@ -154,6 +241,182 @@ t.test('cache add multiple pkgs', t => { }) }) +t.test('cache ls', t => { + t.teardown(() => { + outputOutput = [] + logOutput = [] + }) + setupCacacheFixture() + cache.exec(['ls'], err => { + t.error(err) + t.strictSame(outputOutput, [ + 'make-fetch-happen:request-cache:https://registry.npmjs.org/@fritzy/staydown/-/@fritzy/staydown-3.1.1.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/@fritzy%2fstaydown', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/@gar/npm-expansion/-/@gar/npm-expansion-2.1.0.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/@gar/npm-expansion/-/@gar/npm-expansion-3.0.0-beta.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/@gar%2fnpm-expansion', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/ape-ecs', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/ape-ecs/-/ape-ecs-2.1.7.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/corrupted', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/corrupted/-/corrupted-3.1.0.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/foo', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/foo/-/foo-1.2.3-beta.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-dist', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-dist/-/missing-dist-23.0.0.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-version', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-version/-/missing-version-16.2.0.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/npm', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/npm/-/npm-1.2.0.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz', + 'make-fetch-happen:request-cache:https://somerepo.github.org/aabbcc/14', + 'make-fetch-happen:request-cache:https://somerepo.github.org/extemporaneously', + ]) + t.end() + }) +}) + +t.test('cache ls pkgs', t => { + t.teardown(() => { + outputOutput = [] + }) + cache.exec(['ls', 'webpack@>4.44.1', 'npm'], err => { + t.error(err) + t.strictSame(outputOutput, [ + 'make-fetch-happen:request-cache:https://registry.npmjs.org/npm', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/npm/-/npm-1.2.0.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz', + ]) + t.end() + }) +}) + +t.test('cache ls special', t => { + t.teardown(() => { + outputOutput = [] + }) + cache.exec(['ls', 'foo@1.2.3-beta'], err => { + t.error(err) + t.strictSame(outputOutput, [ + 'make-fetch-happen:request-cache:https://registry.npmjs.org/foo', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/foo/-/foo-1.2.3-beta.tgz', + ]) + t.end() + }) +}) + +t.test('cache ls nonpublic registry', t => { + t.teardown(() => { + outputOutput = [] + }) + cache.exec(['ls', 'extemporaneously'], err => { + t.error(err) + t.strictSame(outputOutput, [ + 'make-fetch-happen:request-cache:https://somerepo.github.org/aabbcc/14', + 'make-fetch-happen:request-cache:https://somerepo.github.org/extemporaneously', + ]) + t.end() + }) +}) + +t.test('cache ls tagged', t => { + t.teardown(() => { + outputOutput = [] + }) + cache.exec(['ls', 'webpack@latest'], err => { + t.match(err.message, 'tagged package', 'should throw warning') + t.end() + }) +}) + +t.test('cache ls scoped and scoped slash', t => { + t.teardown(() => { + outputOutput = [] + }) + cache.exec(['ls', '@fritzy/staydown', '@gar/npm-expansion'], err => { + t.error(err) + t.strictSame(outputOutput, [ + 'make-fetch-happen:request-cache:https://registry.npmjs.org/@fritzy/staydown/-/@fritzy/staydown-3.1.1.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/@fritzy%2fstaydown', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/@gar/npm-expansion/-/@gar/npm-expansion-2.1.0.tgz', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/@gar%2fnpm-expansion', + ]) + t.end() + }) +}) + +t.test('cache ls corrupted', t => { + t.teardown(() => { + outputOutput = [] + }) + cache.exec(['ls', 'corrupted'], err => { + t.error(err) + t.strictSame(outputOutput, [ + 'make-fetch-happen:request-cache:https://registry.npmjs.org/corrupted', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/corrupted/-/corrupted-3.1.0.tgz', + ]) + t.end() + }) +}) + +t.test('cache ls missing packument dist', t => { + t.teardown(() => { + outputOutput = [] + }) + cache.exec(['ls', 'missing-dist'], err => { + t.error(err) + t.strictSame(outputOutput, [ + 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-dist', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-dist/-/missing-dist-23.0.0.tgz', + ]) + t.end() + }) +}) + +t.test('cache ls missing packument version not an object', t => { + t.teardown(() => { + outputOutput = [] + }) + cache.exec(['ls', 'missing-version'], err => { + t.error(err) + t.strictSame(outputOutput, [ + 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-version', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/missing-version/-/missing-version-16.2.0.tgz', + ]) + t.end() + }) +}) + +t.test('cache rm', t => { + t.teardown(() => { + outputOutput = [] + }) + cache.exec(['rm', + 'make-fetch-happen:request-cache:https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz'], err => { + t.error(err) + t.strictSame(outputOutput, [ + 'Deleted: make-fetch-happen:request-cache:https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz', + ]) + t.end() + }) +}) + +t.test('cache rm unfound', t => { + t.teardown(() => { + outputOutput = [] + logOutput = [] + }) + cache.exec(['rm', 'made-up-key'], err => { + t.error(err) + t.strictSame(logOutput, [ + ['warn', 'Not Found: made-up-key'], + ], 'logs correctly') + t.end() + }) +}) + t.test('cache verify', t => { t.teardown(() => { outputOutput = [] diff --git a/deps/npm/test/lib/cli.js b/deps/npm/test/lib/cli.js index b85c981cd00..2c0b6c0ba72 100644 --- a/deps/npm/test/lib/cli.js +++ b/deps/npm/test/lib/cli.js @@ -104,6 +104,32 @@ t.test('calling with --versions calls npm version with no args', async t => { t.strictSame(exitHandlerCalled, []) }) +t.test('logged argv is sanitized', async t => { + const proc = processMock({ + argv: ['node', 'npm', 'testcommand', 'https://username:password@npmjs.org/test_url_with_a_password'], + }) + const { npm } = mockNpm(t) + const cli = cliMock(npm) + + npm.commands.testcommand = (args, cb) => { + cb() + } + + await cli(proc) + t.equal(proc.title, 'npm') + t.strictSame(logs, [ + 'pause', + ['verbose', 'cli', [ + 'node', + 'npm', + 'testcommand', + 'https://username:***@npmjs.org/test_url_with_a_password', + ]], + ['info', 'using', 'npm@%s', npm.version], + ['info', 'using', 'node@%s', process.version], + ]) +}) + t.test('print usage if no params provided', async t => { const proc = processMock({ argv: ['node', 'npm'], diff --git a/deps/npm/test/lib/find-dupes.js b/deps/npm/test/lib/find-dupes.js index c7b33ceb6ed..17940764b94 100644 --- a/deps/npm/test/lib/find-dupes.js +++ b/deps/npm/test/lib/find-dupes.js @@ -1,24 +1,26 @@ const t = require('tap') -const FindDupes = require('../../lib/find-dupes.js') +const { real: mockNpm } = require('../fixtures/mock-npm') -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) - }, +t.test('should run dedupe in dryRun mode', async (t) => { + t.plan(5) + const { npm, command } = mockNpm(t, { + '@npmcli/arborist': function (args) { + t.ok(args, 'gets options object') + t.ok(args.path, 'gets path option') + t.ok(args.dryRun, 'is called in dryRun mode') + this.dedupe = () => { + t.ok(true, 'dedupe is called') + } }, - commands: { - dedupe: (args, cb) => { - t.match(args, []) - cb() - }, + '../../lib/utils/reify-finish.js': (npm, arb) => { + t.ok(arb, 'gets arborist tree') }, }) - findDupesTest.exec({}, () => { - t.end() - }) + await npm.load() + // explicitly set to false so we can be 100% sure it's always true when it + // hits arborist + npm.config.set('dry-run', false) + npm.config.set('prefix', 'foo') + await command('find-dupes') }) diff --git a/deps/npm/test/lib/get.js b/deps/npm/test/lib/get.js index 9b77fbba3e6..30e26b7453f 100644 --- a/deps/npm/test/lib/get.js +++ b/deps/npm/test/lib/get.js @@ -1,16 +1,16 @@ const t = require('tap') +const { real: mockNpm } = require('../fixtures/mock-npm') -t.test('should retrieve values from npm.commands.config', (t) => { - const Get = t.mock('../../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.exec(['foo']) +t.test('should retrieve values from config', async t => { + const { joinedOutput, command, npm } = mockNpm(t) + const name = 'editor' + const value = 'vigor' + await npm.load() + npm.config.set(name, value) + await command('get', [name]) + t.equal( + joinedOutput(), + value, + 'outputs config item' + ) }) diff --git a/deps/npm/test/lib/load-all.js b/deps/npm/test/lib/load-all.js index e6e40780534..c38c244934e 100644 --- a/deps/npm/test/lib/load-all.js +++ b/deps/npm/test/lib/load-all.js @@ -1,15 +1,24 @@ const t = require('tap') const glob = require('glob') const { resolve } = require('path') +const { real: mockNpm } = require('../fixtures/mock-npm') const full = process.env.npm_lifecycle_event === 'check-coverage' if (!full) t.pass('nothing to do here, not checking for full coverage') else { - // some files do config.get() on load, so have to load npm first - const npm = require('../../lib/npm.js') - t.test('load npm first', t => npm.load(t.end)) + const { npm } = mockNpm(t) + + t.teardown(() => { + const exitHandler = require('../../lib/utils/exit-handler.js') + exitHandler.setNpm(npm) + exitHandler() + }) + + t.test('load npm first', async t => { + await npm.load() + }) t.test('load all the files', t => { // just load all the files so we measure coverage for the missing tests @@ -21,11 +30,4 @@ else { t.pass('loaded all files') t.end() }) - - t.test('call the exit handler so we dont freak out', t => { - const exitHandler = require('../../lib/utils/exit-handler.js') - exitHandler.setNpm(npm) - exitHandler() - t.end() - }) } diff --git a/deps/npm/test/lib/prefix.js b/deps/npm/test/lib/prefix.js index 526631388e7..18a37f3ccd1 100644 --- a/deps/npm/test/lib/prefix.js +++ b/deps/npm/test/lib/prefix.js @@ -1,19 +1,13 @@ const t = require('tap') +const { real: mockNpm } = require('../fixtures/mock-npm') -t.test('prefix', (t) => { - t.plan(3) - const dir = '/prefix/dir' - - const Prefix = require('../../lib/prefix.js') - const prefix = new Prefix({ - prefix: dir, - output: (output) => { - t.equal(output, dir, 'prints the correct directory') - }, - }) - - prefix.exec([], (err) => { - t.error(err, 'npm prefix') - t.ok('should have printed directory') - }) +t.test('prefix', async (t) => { + const { joinedOutput, command, npm } = mockNpm(t) + await npm.load() + await command('prefix') + t.equal( + joinedOutput(), + npm.prefix, + 'outputs npm.prefix' + ) }) diff --git a/deps/npm/test/lib/prune.js b/deps/npm/test/lib/prune.js index 87bb1370f3a..3e47feb4613 100644 --- a/deps/npm/test/lib/prune.js +++ b/deps/npm/test/lib/prune.js @@ -1,7 +1,9 @@ const t = require('tap') +const { real: mockNpm } = require('../fixtures/mock-npm') -t.test('should prune using Arborist', (t) => { - const Prune = t.mock('../../lib/prune.js', { +t.test('should prune using Arborist', async (t) => { + t.plan(4) + const { command, npm } = mockNpm(t, { '@npmcli/arborist': function (args) { t.ok(args, 'gets options object') t.ok(args.path, 'gets path option') @@ -13,16 +15,6 @@ t.test('should prune using Arborist', (t) => { t.ok(arb, 'gets arborist tree') }, }) - const prune = new Prune({ - prefix: 'foo', - flatOptions: { - foo: 'bar', - }, - }) - prune.exec(null, er => { - if (er) - throw er - t.ok(true, 'callback is called') - t.end() - }) + await npm.load() + await command('prune') }) diff --git a/deps/npm/test/lib/restart.js b/deps/npm/test/lib/restart.js index 9719476c418..153c3144728 100644 --- a/deps/npm/test/lib/restart.js +++ b/deps/npm/test/lib/restart.js @@ -1,16 +1,36 @@ const t = require('tap') -let runArgs -const npm = { - commands: { - 'run-script': (args, cb) => { - runArgs = args - cb() - }, - }, -} -const Restart = require('../../lib/restart.js') -const restart = new Restart(npm) -restart.exec(['foo'], () => { - t.match(runArgs, ['restart', 'foo']) - t.end() +const spawk = require('spawk') +const { real: mockNpm } = require('../fixtures/mock-npm') + +spawk.preventUnmatched() +t.teardown(() => { + spawk.unload() +}) + +// TODO this ... smells. npm "script-shell" config mentions defaults but those +// are handled by run-script, not npm. So for now we have to tie tests to some +// pretty specific internals of runScript +const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js') + +t.test('should run stop script from package.json', async t => { + const prefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'x', + version: '1.2.3', + scripts: { + restart: 'node ./test-restart.js', + }, + }), + }) + const { command, npm } = mockNpm(t) + await npm.load() + npm.log.level = 'silent' + npm.localPrefix = prefix + const [scriptShell] = makeSpawnArgs({ path: prefix }) + const script = spawk.spawn(scriptShell, (args) => { + t.ok(args.includes('node ./test-restart.js "foo"'), 'ran stop script with extra args') + return true + }) + await command('restart', ['foo']) + t.ok(script.called, 'script ran') }) diff --git a/deps/npm/test/lib/root.js b/deps/npm/test/lib/root.js index 5460f3d4985..7b91654c6c9 100644 --- a/deps/npm/test/lib/root.js +++ b/deps/npm/test/lib/root.js @@ -1,19 +1,13 @@ const t = require('tap') +const { real: mockNpm } = require('../fixtures/mock-npm') -t.test('root', (t) => { - t.plan(3) - const dir = '/root/dir' - - const Root = require('../../lib/root.js') - const root = new Root({ - dir, - output: (output) => { - t.equal(output, dir, 'prints the correct directory') - }, - }) - - root.exec([], (err) => { - t.error(err, 'npm root') - t.ok('should have printed directory') - }) +t.test('prefix', async (t) => { + const { joinedOutput, command, npm } = mockNpm(t) + await npm.load() + await command('root') + t.equal( + joinedOutput(), + npm.dir, + 'outputs npm.dir' + ) }) diff --git a/deps/npm/test/lib/set.js b/deps/npm/test/lib/set.js index f51065a4b29..14d094001b4 100644 --- a/deps/npm/test/lib/set.js +++ b/deps/npm/test/lib/set.js @@ -1,5 +1,32 @@ const t = require('tap') +// can't run this until npm set can save to npm.localPrefix +t.skip('npm set', async t => { + const { real: mockNpm } = require('../fixtures/mock-npm') + const { joinedOutput, command, npm } = mockNpm(t) + await npm.load() + + t.test('no args', async t => { + t.rejects( + command('set'), + /Usage:/, + 'prints usage' + ) + }) + + t.test('test-config-item', async t => { + npm.localPrefix = t.testdir({}) + t.not(npm.config.get('test-config-item', 'project'), 'test config value', 'config is not already new value') + // This will write to ~/.npmrc! + // Don't unskip until we can write to project level + await command('set', ['test-config-item=test config value']) + t.equal(joinedOutput(), '', 'outputs nothing') + t.equal(npm.config.get('test-config-item', 'project'), 'test config value', 'config is set to new value') + }) +}) + +// Everything after this can go away once the above test is unskipped + let configArgs = null const npm = { commands: { diff --git a/deps/npm/test/lib/start.js b/deps/npm/test/lib/start.js index 4e77f9691b8..5c38c71a9a6 100644 --- a/deps/npm/test/lib/start.js +++ b/deps/npm/test/lib/start.js @@ -1,16 +1,36 @@ const t = require('tap') -let runArgs -const npm = { - commands: { - 'run-script': (args, cb) => { - runArgs = args - cb() - }, - }, -} -const Start = require('../../lib/start.js') -const start = new Start(npm) -start.exec(['foo'], () => { - t.match(runArgs, ['start', 'foo']) - t.end() +const spawk = require('spawk') +const { real: mockNpm } = require('../fixtures/mock-npm') + +spawk.preventUnmatched() +t.teardown(() => { + spawk.unload() +}) + +// TODO this ... smells. npm "script-shell" config mentions defaults but those +// are handled by run-script, not npm. So for now we have to tie tests to some +// pretty specific internals of runScript +const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js') + +t.test('should run stop script from package.json', async t => { + const prefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'x', + version: '1.2.3', + scripts: { + start: 'node ./test-start.js', + }, + }), + }) + const { command, npm } = mockNpm(t) + await npm.load() + npm.log.level = 'silent' + npm.localPrefix = prefix + const [scriptShell] = makeSpawnArgs({ path: prefix }) + const script = spawk.spawn(scriptShell, (args) => { + t.ok(args.includes('node ./test-start.js "foo"'), 'ran start script with extra args') + return true + }) + await command('start', ['foo']) + t.ok(script.called, 'script ran') }) diff --git a/deps/npm/test/lib/stop.js b/deps/npm/test/lib/stop.js index 92ca84bd874..04cdb4e5e75 100644 --- a/deps/npm/test/lib/stop.js +++ b/deps/npm/test/lib/stop.js @@ -1,16 +1,36 @@ const t = require('tap') -let runArgs -const npm = { - commands: { - 'run-script': (args, cb) => { - runArgs = args - cb() - }, - }, -} -const Stop = require('../../lib/stop.js') -const stop = new Stop(npm) -stop.exec(['foo'], () => { - t.match(runArgs, ['stop', 'foo']) - t.end() +const spawk = require('spawk') +const { real: mockNpm } = require('../fixtures/mock-npm') + +spawk.preventUnmatched() +t.teardown(() => { + spawk.unload() +}) + +// TODO this ... smells. npm "script-shell" config mentions defaults but those +// are handled by run-script, not npm. So for now we have to tie tests to some +// pretty specific internals of runScript +const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js') + +t.test('should run stop script from package.json', async t => { + const prefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'x', + version: '1.2.3', + scripts: { + stop: 'node ./test-stop.js', + }, + }), + }) + const { command, npm } = mockNpm(t) + await npm.load() + npm.log.level = 'silent' + npm.localPrefix = prefix + const [scriptShell] = makeSpawnArgs({ path: prefix }) + const script = spawk.spawn(scriptShell, (args) => { + t.ok(args.includes('node ./test-stop.js "foo"'), 'ran stop script with extra args') + return true + }) + await command('stop', ['foo']) + t.ok(script.called, 'script ran') }) diff --git a/deps/npm/test/lib/test.js b/deps/npm/test/lib/test.js index c151b1e8253..d597ba27438 100644 --- a/deps/npm/test/lib/test.js +++ b/deps/npm/test/lib/test.js @@ -1,38 +1,36 @@ const t = require('tap') -let RUN_ARGS = null -const npm = { - commands: { - 'run-script': (args, cb) => { - RUN_ARGS = args - cb() - }, - }, -} -const Test = require('../../lib/test.js') -const test = new Test(npm) +const spawk = require('spawk') +const { real: mockNpm } = require('../fixtures/mock-npm') -t.test('run a test', t => { - test.exec([], (er) => { - t.strictSame(RUN_ARGS, ['test'], 'added "test" to the args') - }) - test.exec(['hello', 'world'], (er) => { - t.strictSame(RUN_ARGS, ['test', 'hello', 'world'], 'added positional args') - }) +spawk.preventUnmatched() +t.teardown(() => { + spawk.unload() +}) - const lcErr = Object.assign(new Error('should not see this'), { - code: 'ELIFECYCLE', - }) - const otherErr = new Error('should see this') +// TODO this ... smells. npm "script-shell" config mentions defaults but those +// are handled by run-script, not npm. So for now we have to tie tests to some +// pretty specific internals of runScript +const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js') - npm.commands['run-script'] = (args, cb) => cb(lcErr) - test.exec([], (er) => { - t.equal(er, 'Test failed. See above for more details.') +t.test('should run stop script from package.json', async t => { + const prefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'x', + version: '1.2.3', + scripts: { + test: 'node ./test-test.js', + }, + }), }) - - npm.commands['run-script'] = (args, cb) => cb(otherErr) - test.exec([], (er) => { - t.match(er, { message: 'should see this' }) + const { command, npm } = mockNpm(t) + await npm.load() + npm.log.level = 'silent' + npm.localPrefix = prefix + const [scriptShell] = makeSpawnArgs({ path: prefix }) + const script = spawk.spawn(scriptShell, (args) => { + t.ok(args.includes('node ./test-test.js "foo"'), 'ran test script with extra args') + return true }) - - t.end() + await command('test', ['foo']) + t.ok(script.called, 'script ran') }) diff --git a/deps/npm/test/lib/utils/completion/installed-deep.js b/deps/npm/test/lib/utils/completion/installed-deep.js index 21e77a568bd..aa0d85ec10a 100644 --- a/deps/npm/test/lib/utils/completion/installed-deep.js +++ b/deps/npm/test/lib/utils/completion/installed-deep.js @@ -219,6 +219,8 @@ t.test('limit depth', async t => { [ ['bar', '-g'], ['foo', '-g'], + // XXX https://github.com/npm/statusboard/issues/380 + ['a-bar', '-g'], 'a', 'b', 'c', 'ch', 'd', 'e', @@ -248,6 +250,8 @@ t.test('limit depth as global', async t => { [ 'bar', 'foo', + // https://github.com/npm/statusboard/issues/380 + 'a-bar', ], 'should reorder so that packages above that level depth goes last' ) diff --git a/deps/npm/test/lib/utils/error-message.js b/deps/npm/test/lib/utils/error-message.js index 908d70fc392..07328d58875 100644 --- a/deps/npm/test/lib/utils/error-message.js +++ b/deps/npm/test/lib/utils/error-message.js @@ -292,7 +292,7 @@ t.test('json parse', t => { process.argv = ['arg', 'v'] t.matchSnapshot(errorMessage(Object.assign(new Error('conflicted'), { code: 'EJSONPARSE', - file: resolve(dir, 'package.json'), + path: resolve(dir, 'package.json'), }), npm)) t.end() }) @@ -314,7 +314,7 @@ t.test('json parse', t => { process.argv = ['arg', 'v'] t.matchSnapshot(errorMessage(Object.assign(new Error('not json'), { code: 'EJSONPARSE', - file: resolve(dir, 'package.json'), + path: resolve(dir, 'package.json'), }), npm)) t.end() }) @@ -330,7 +330,7 @@ t.test('json parse', t => { process.argv = ['arg', 'v'] t.matchSnapshot(errorMessage(Object.assign(new Error('not json'), { code: 'EJSONPARSE', - file: `${dir}/blerg.json`, + path: `${dir}/blerg.json`, }), npm)) t.end() }) diff --git a/deps/npm/test/lib/utils/tar.js b/deps/npm/test/lib/utils/tar.js index 2662d47ace4..19d94916945 100644 --- a/deps/npm/test/lib/utils/tar.js +++ b/deps/npm/test/lib/utils/tar.js @@ -57,6 +57,8 @@ t.test('should log tarball contents with unicode', async (t) => { logTar({ files: [], bundled: [], + size: 0, + unpackedSize: 0, integrity: '', }, { unicode: true }) t.end() @@ -75,6 +77,8 @@ t.test('should default to npmlog', async (t) => { logTar({ files: [], bundled: [], + size: 0, + unpackedSize: 0, integrity: '', }) t.end() diff --git a/deps/npm/test/lib/whoami.js b/deps/npm/test/lib/whoami.js index 9190e3858b1..c54ee2a5a2b 100644 --- a/deps/npm/test/lib/whoami.js +++ b/deps/npm/test/lib/whoami.js @@ -1,41 +1,25 @@ const t = require('tap') -const { fake: mockNpm } = require('../fixtures/mock-npm') +const { real: mockNpm } = require('../fixtures/mock-npm') -t.test('whoami', (t) => { - t.plan(3) - const Whoami = t.mock('../../lib/whoami.js', { - '../../lib/utils/get-identity.js': () => Promise.resolve('foo'), - }) - const npm = mockNpm({ - config: { json: false }, - output: (output) => { - t.equal(output, 'foo', 'should output the username') - }, - }) - - const whoami = new Whoami(npm) +const username = 'foo' +const { joinedOutput, command, npm } = mockNpm(t, { + '../../lib/utils/get-identity.js': () => Promise.resolve(username), +}) - whoami.exec([], (err) => { - t.error(err, 'npm whoami') - t.ok('should successfully print username') - }) +t.before(async () => { + await npm.load() }) -t.test('whoami json', (t) => { - t.plan(3) - const Whoami = t.mock('../../lib/whoami.js', { - '../../lib/utils/get-identity.js': () => Promise.resolve('foo'), - }) - const npm = mockNpm({ - config: { json: true }, - output: (output) => { - t.equal(output, '"foo"', 'should output the username') - }, - }) - const whoami = new Whoami(npm) +t.test('npm whoami', async (t) => { + await command('whoami') + t.equal(joinedOutput(), username, 'should print username') +}) - whoami.exec([], (err) => { - t.error(err, 'npm whoami') - t.ok('should successfully print username as json') +t.test('npm whoami --json', async (t) => { + t.teardown(() => { + npm.config.set('json', false) }) + npm.config.set('json', true) + await command('whoami') + t.equal(JSON.parse(joinedOutput()), username, 'should print username') }) |