summaryrefslogtreecommitdiff
path: root/deps/npm/test/lib
diff options
context:
space:
mode:
authorRuy Adorno <ruyadorno@hotmail.com>2021-03-23 14:58:11 -0400
committerRuy Adorno <ruyadorno@hotmail.com>2021-03-23 22:10:30 -0400
commit73b3e06c910549a7fd3c8f49324ab14e0adf2c8d (patch)
treee7f0ab70d8bb09a6212f8a22da25dc07410e6967 /deps/npm/test/lib
parentf2090877f1f727020099ef9e30cc70e10b10f900 (diff)
downloadnode-new-73b3e06c910549a7fd3c8f49324ab14e0adf2c8d.tar.gz
deps: upgrade npm to 7.7.0
PR-URL: https://github.com/nodejs/node/pull/37879 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Diffstat (limited to 'deps/npm/test/lib')
-rw-r--r--deps/npm/test/lib/audit.js20
-rw-r--r--deps/npm/test/lib/bin.js19
-rw-r--r--deps/npm/test/lib/birthday.js19
-rw-r--r--deps/npm/test/lib/cache.js31
-rw-r--r--deps/npm/test/lib/ci.js36
-rw-r--r--deps/npm/test/lib/cli.js127
-rw-r--r--deps/npm/test/lib/completion.js13
-rw-r--r--deps/npm/test/lib/config.js59
-rw-r--r--deps/npm/test/lib/dedupe.js31
-rw-r--r--deps/npm/test/lib/diff.js190
-rw-r--r--deps/npm/test/lib/dist-tag.js48
-rw-r--r--deps/npm/test/lib/exec.js222
-rw-r--r--deps/npm/test/lib/fund.js108
-rw-r--r--deps/npm/test/lib/help-search.js71
-rw-r--r--deps/npm/test/lib/help.js88
-rw-r--r--deps/npm/test/lib/init.js48
-rw-r--r--deps/npm/test/lib/install.js35
-rw-r--r--deps/npm/test/lib/link.js15
-rw-r--r--deps/npm/test/lib/load-all-commands.js54
-rw-r--r--deps/npm/test/lib/logout.js72
-rw-r--r--deps/npm/test/lib/ls.js522
-rw-r--r--deps/npm/test/lib/npm.js104
-rw-r--r--deps/npm/test/lib/outdated.js72
-rw-r--r--deps/npm/test/lib/pack.js29
-rw-r--r--deps/npm/test/lib/ping.js39
-rw-r--r--deps/npm/test/lib/profile.js105
-rw-r--r--deps/npm/test/lib/publish.js241
-rw-r--r--deps/npm/test/lib/rebuild.js20
-rw-r--r--deps/npm/test/lib/run-script.js528
-rw-r--r--deps/npm/test/lib/search.js20
-rw-r--r--deps/npm/test/lib/set-script.js5
-rw-r--r--deps/npm/test/lib/shrinkwrap.js32
-rw-r--r--deps/npm/test/lib/star.js24
-rw-r--r--deps/npm/test/lib/uninstall.js21
-rw-r--r--deps/npm/test/lib/unpublish.js43
-rw-r--r--deps/npm/test/lib/update.js20
-rw-r--r--deps/npm/test/lib/utils/config.js143
-rw-r--r--deps/npm/test/lib/utils/config/definition.js185
-rw-r--r--deps/npm/test/lib/utils/config/definitions.js697
-rw-r--r--deps/npm/test/lib/utils/config/describe-all.js6
-rw-r--r--deps/npm/test/lib/utils/config/flatten.js34
-rw-r--r--deps/npm/test/lib/utils/config/index.js24
-rw-r--r--deps/npm/test/lib/utils/did-you-mean.js42
-rw-r--r--deps/npm/test/lib/utils/flat-options.js359
-rw-r--r--deps/npm/test/lib/utils/lifecycle-cmd.js6
-rw-r--r--deps/npm/test/lib/utils/npm-usage.js63
-rw-r--r--deps/npm/test/lib/utils/read-local-package.js21
-rw-r--r--deps/npm/test/lib/utils/tar.js4
-rw-r--r--deps/npm/test/lib/version.js20
-rw-r--r--deps/npm/test/lib/view.js90
-rw-r--r--deps/npm/test/lib/whoami.js14
-rw-r--r--deps/npm/test/lib/workspaces/get-workspaces.js199
52 files changed, 3170 insertions, 1868 deletions
diff --git a/deps/npm/test/lib/audit.js b/deps/npm/test/lib/audit.js
index d291ef8794..a25e6b0e27 100644
--- a/deps/npm/test/lib/audit.js
+++ b/deps/npm/test/lib/audit.js
@@ -1,5 +1,6 @@
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
t.test('should audit using Arborist', t => {
let ARB_ARGS = null
@@ -9,15 +10,15 @@ t.test('should audit using Arborist', t => {
let OUTPUT_CALLED = false
let ARB_OBJ = null
- const npm = {
+ const npm = mockNpm({
prefix: 'foo',
- flatOptions: {
+ config: {
json: false,
},
output: () => {
OUTPUT_CALLED = true
},
- }
+ })
const Audit = requireInject('../../lib/audit.js', {
'npm-audit-report': () => {
AUDIT_REPORT_CALLED = true
@@ -65,13 +66,13 @@ t.test('should audit using Arborist', t => {
})
t.test('should audit - json', t => {
- const npm = {
+ const npm = mockNpm({
prefix: 'foo',
- flatOptions: {
+ config: {
json: true,
},
output: () => {},
- }
+ })
const Audit = requireInject('../../lib/audit.js', {
'npm-audit-report': () => ({
@@ -98,9 +99,12 @@ t.test('report endpoint error', t => {
t.test(`json=${json}`, t => {
const OUTPUT = []
const LOGS = []
- const npm = {
+ const npm = mockNpm({
prefix: 'foo',
command: 'audit',
+ config: {
+ json,
+ },
flatOptions: {
json,
},
@@ -110,7 +114,7 @@ t.test('report endpoint error', t => {
output: (...msg) => {
OUTPUT.push(msg)
},
- }
+ })
const Audit = requireInject('../../lib/audit.js', {
'npm-audit-report': () => {
throw new Error('should not call audit report when there are errors')
diff --git a/deps/npm/test/lib/bin.js b/deps/npm/test/lib/bin.js
index 428b2e3bad..1d9341169b 100644
--- a/deps/npm/test/lib/bin.js
+++ b/deps/npm/test/lib/bin.js
@@ -1,5 +1,6 @@
const { test } = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
test('bin', (t) => {
t.plan(4)
@@ -7,13 +8,13 @@ test('bin', (t) => {
const Bin = require('../../lib/bin.js')
- const npm = {
+ const npm = mockNpm({
bin: dir,
- flatOptions: { global: false },
+ config: { global: false },
output: (output) => {
t.equal(output, dir, 'prints the correct directory')
},
- }
+ })
const bin = new Bin(npm)
t.match(bin.usage, 'bin', 'usage has command name in it')
@@ -39,13 +40,13 @@ test('bin -g', (t) => {
'../../lib/utils/path.js': [dir],
})
- const npm = {
+ const npm = mockNpm({
bin: dir,
- flatOptions: { global: true },
+ config: { global: true },
output: (output) => {
t.equal(output, dir, 'prints the correct directory')
},
- }
+ })
const bin = new Bin(npm)
bin.exec([], (err) => {
@@ -69,13 +70,13 @@ test('bin -g (not in path)', (t) => {
const Bin = requireInject('../../lib/bin.js', {
'../../lib/utils/path.js': ['/not/my/dir'],
})
- const npm = {
+ const npm = mockNpm({
bin: dir,
- flatOptions: { global: true },
+ config: { global: true },
output: (output) => {
t.equal(output, dir, 'prints the correct directory')
},
- }
+ })
const bin = new Bin(npm)
bin.exec([], (err) => {
diff --git a/deps/npm/test/lib/birthday.js b/deps/npm/test/lib/birthday.js
index c818223fb5..0589be7a8e 100644
--- a/deps/npm/test/lib/birthday.js
+++ b/deps/npm/test/lib/birthday.js
@@ -1,20 +1,23 @@
const t = require('tap')
-const npm = {
- flatOptions: {
- yes: false,
- package: [],
- },
+const mockNpm = require('../fixtures/mock-npm')
+
+const config = {
+ yes: false,
+ package: [],
+}
+const npm = mockNpm({
+ config,
commands: {
exec: (args, cb) => {
- t.equal(npm.flatOptions.yes, true, 'should say yes')
- t.strictSame(npm.flatOptions.package, ['@npmcli/npm-birthday'],
+ t.equal(npm.config.get('yes'), true, 'should say yes')
+ t.strictSame(npm.config.get('package'), ['@npmcli/npm-birthday'],
'uses correct package')
t.strictSame(args, ['npm-birthday'], 'called with correct args')
t.match(cb, Function, 'callback is a function')
cb()
},
},
-}
+})
const Birthday = require('../../lib/birthday.js')
const birthday = new Birthday(npm)
diff --git a/deps/npm/test/lib/cache.js b/deps/npm/test/lib/cache.js
index 773adc6a8a..0fdf768568 100644
--- a/deps/npm/test/lib/cache.js
+++ b/deps/npm/test/lib/cache.js
@@ -1,23 +1,12 @@
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const path = require('path')
const usageUtil = () => 'usage instructions'
-const flatOptions = {
- force: false,
-}
-
let outputOutput = []
-const npm = {
- flatOptions,
- cache: '/fake/path',
- output: (msg) => {
- outputOutput.push(msg)
- },
-}
-
let rimrafPath = ''
const rimraf = (path, cb) => {
rimrafPath = path
@@ -66,6 +55,14 @@ const Cache = requireInject('../../lib/cache.js', {
'../../lib/utils/usage.js': usageUtil,
})
+const npm = mockNpm({
+ cache: '/fake/path',
+ flatOptions: { force: false },
+ config: { force: false },
+ output: (msg) => {
+ outputOutput.push(msg)
+ },
+})
const cache = new Cache(npm)
t.test('cache no args', t => {
@@ -83,10 +80,12 @@ t.test('cache clean', t => {
})
t.test('cache clean (force)', t => {
- flatOptions.force = true
+ npm.config.set('force', true)
+ npm.flatOptions.force = true
t.teardown(() => {
rimrafPath = ''
- flatOptions.force = false
+ npm.config.force = false
+ npm.flatOptions.force = false
})
cache.exec(['clear'], err => {
@@ -131,7 +130,7 @@ t.test('cache add pkg only', t => {
['silly', 'cache add', 'spec', 'mypkg'],
], 'logs correctly')
t.equal(tarballStreamSpec, 'mypkg', 'passes the correct spec to pacote')
- t.same(tarballStreamOpts, flatOptions, 'passes the correct options to pacote')
+ t.same(tarballStreamOpts, npm.flatOptions, 'passes the correct options to pacote')
t.end()
})
})
@@ -150,7 +149,7 @@ t.test('cache add pkg w/ spec modifier', t => {
['silly', 'cache add', 'spec', 'mypkg@latest'],
], 'logs correctly')
t.equal(tarballStreamSpec, 'mypkg@latest', 'passes the correct spec to pacote')
- t.same(tarballStreamOpts, flatOptions, 'passes the correct options to pacote')
+ t.same(tarballStreamOpts, npm.flatOptions, 'passes the correct options to pacote')
t.end()
})
})
diff --git a/deps/npm/test/lib/ci.js b/deps/npm/test/lib/ci.js
index 3419218ef9..7f06a6cebc 100644
--- a/deps/npm/test/lib/ci.js
+++ b/deps/npm/test/lib/ci.js
@@ -5,6 +5,7 @@ const readdir = util.promisify(fs.readdir)
const { test } = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
test('should ignore scripts with --ignore-scripts', (t) => {
const SCRIPTS = []
@@ -22,17 +23,15 @@ test('should ignore scripts with --ignore-scripts', (t) => {
},
})
- const ci = new CI({
+ const npm = mockNpm({
globalDir: 'path/to/node_modules/',
prefix: 'foo',
- flatOptions: {
- global: false,
- ignoreScripts: true,
- },
config: {
- get: () => false,
+ global: false,
+ 'ignore-scripts': true,
},
})
+ const ci = new CI(npm)
ci.exec([], er => {
if (er)
@@ -115,12 +114,13 @@ test('should use Arborist and run-script', (t) => {
},
})
- const ci = new CI({
+ const npm = mockNpm({
prefix: path,
- flatOptions: {
+ config: {
global: false,
},
})
+ const ci = new CI(npm)
ci.exec(null, er => {
if (er)
@@ -146,12 +146,13 @@ test('should pass flatOptions to Arborist.reify', (t) => {
}
},
})
- const ci = new CI({
+ const npm = mockNpm({
prefix: 'foo',
flatOptions: {
production: true,
},
})
+ const ci = new CI(npm)
ci.exec(null, er => {
if (er)
throw er
@@ -173,14 +174,15 @@ test('should throw if package-lock.json or npm-shrinkwrap missing', (t) => {
},
},
})
- const ci = new CI({
+ const npm = mockNpm({
prefix: testDir,
- flatOptions: {
+ config: {
global: false,
},
})
+ const ci = new CI(npm)
ci.exec(null, (err, res) => {
- t.ok(err, 'throws error when there is no package-lock')
+ t.match(err, /package-lock.json/, 'throws error when there is no package-lock')
t.notOk(res)
t.end()
})
@@ -191,12 +193,13 @@ test('should throw ECIGLOBAL', (t) => {
'@npmcli/run-script': opts => {},
'../../lib/utils/reify-finish.js': async () => {},
})
- const ci = new CI({
+ const npm = mockNpm({
prefix: 'foo',
- flatOptions: {
+ config: {
global: true,
},
})
+ const ci = new CI(npm)
ci.exec(null, (err, res) => {
t.equals(err.code, 'ECIGLOBAL', 'throws error with global packages')
t.notOk(res)
@@ -227,12 +230,13 @@ test('should remove existing node_modules before installing', (t) => {
},
})
- const ci = new CI({
+ const npm = mockNpm({
prefix: testDir,
- flatOptions: {
+ config: {
global: false,
},
})
+ const ci = new CI(npm)
ci.exec(null, er => {
if (er)
diff --git a/deps/npm/test/lib/cli.js b/deps/npm/test/lib/cli.js
index b5441be1e4..40da77bf44 100644
--- a/deps/npm/test/lib/cli.js
+++ b/deps/npm/test/lib/cli.js
@@ -1,7 +1,11 @@
const t = require('tap')
let LOAD_ERROR = null
+const npmOutputs = []
const npmock = {
+ log: { level: 'silent' },
+ output: (...msg) => npmOutputs.push(msg),
+ usage: 'npm usage test example',
version: '99.99.99',
load: cb => cb(LOAD_ERROR),
argv: [],
@@ -21,8 +25,11 @@ const unsupportedMock = {
}
let errorHandlerCalled = null
+let errorHandlerCb
const errorHandlerMock = (...args) => {
errorHandlerCalled = args
+ if (errorHandlerCb)
+ errorHandlerCb()
}
let errorHandlerExitCalled = null
errorHandlerMock.exit = code => {
@@ -39,15 +46,23 @@ const npmlogMock = {
const requireInject = require('require-inject')
const cli = requireInject.installGlobally('../../lib/cli.js', {
'../../lib/npm.js': npmock,
+ '../../lib/utils/did-you-mean.js': () => '\ntest did you mean',
'../../lib/utils/unsupported.js': unsupportedMock,
'../../lib/utils/error-handler.js': errorHandlerMock,
npmlog: npmlogMock,
})
t.test('print the version, and treat npm_g to npm -g', t => {
- const { log } = console
- const consoleLogs = []
- console.log = (...msg) => consoleLogs.push(msg)
+ t.teardown(() => {
+ delete npmock.config.settings.version
+ process.argv = argv
+ npmock.argv.length = 0
+ proc.argv.length = 0
+ logs.length = 0
+ npmOutputs.length = 0
+ errorHandlerExitCalled = null
+ })
+
const { argv } = process
const proc = {
argv: ['node', 'npm_g', '-v'],
@@ -67,25 +82,13 @@ t.test('print the version, and treat npm_g to npm -g', t => {
['info', 'using', 'npm@%s', '99.99.99'],
['info', 'using', 'node@%s', '420.69.lol'],
])
- t.strictSame(consoleLogs, [['99.99.99']])
+ t.strictSame(npmOutputs, [['99.99.99']])
t.strictSame(errorHandlerExitCalled, 0)
- delete npmock.config.settings.version
- process.argv = argv
- console.log = log
- npmock.argv.length = 0
- proc.argv.length = 0
- logs.length = 0
- consoleLogs.length = 0
- errorHandlerExitCalled = null
-
t.end()
})
t.test('calling with --versions calls npm version with no args', t => {
- const { log } = console
- const consoleLogs = []
- console.log = (...msg) => consoleLogs.push(msg)
const processArgv = process.argv
const proc = {
argv: ['node', 'npm', 'install', 'or', 'whatever', '--versions'],
@@ -97,11 +100,10 @@ t.test('calling with --versions calls npm version with no args', t => {
t.teardown(() => {
delete npmock.config.settings.versions
process.argv = processArgv
- console.log = log
npmock.argv.length = 0
proc.argv.length = 0
logs.length = 0
- consoleLogs.length = 0
+ npmOutputs.length = 0
errorHandlerExitCalled = null
delete npmock.commands.version
})
@@ -117,7 +119,7 @@ t.test('calling with --versions calls npm version with no args', t => {
['info', 'using', 'node@%s', undefined],
])
- t.strictSame(consoleLogs, [])
+ t.strictSame(npmOutputs, [])
t.strictSame(errorHandlerExitCalled, null)
t.strictSame(args, [])
@@ -127,55 +129,80 @@ t.test('calling with --versions calls npm version with no args', t => {
cli(proc)
})
-t.test('print usage if -h provided', t => {
- const { log } = console
- const consoleLogs = []
- console.log = (...msg) => consoleLogs.push(msg)
+t.test('print usage if no params provided', t => {
+ const { output } = npmock
+ t.teardown(() => {
+ npmock.output = output
+ })
+ const proc = {
+ argv: ['node', 'npm'],
+ on: () => {},
+ }
+ npmock.argv = []
+ npmock.output = (msg) => {
+ if (msg) {
+ t.match(msg, 'npm usage test example', 'outputs npm usage')
+ t.end()
+ }
+ }
+ cli(proc)
+})
+
+t.test('print usage if non-command param provided', t => {
+ const { output } = npmock
+ t.teardown(() => {
+ npmock.output = output
+ })
const proc = {
argv: ['node', 'npm', 'asdf'],
on: () => {},
}
npmock.argv = ['asdf']
+ npmock.output = (msg) => {
+ if (msg) {
+ t.match(msg, 'Unknown command: "asdf"\ntest did you mean', 'outputs did you mean')
+ t.end()
+ }
+ }
+ cli(proc)
+})
+t.test('gracefully handles error printing usage', t => {
+ const { output } = npmock
t.teardown(() => {
- console.log = log
- npmock.argv.length = 0
- proc.argv.length = 0
- logs.length = 0
- consoleLogs.length = 0
- errorHandlerExitCalled = null
- delete npmock.commands.help
+ npmock.output = output
+ errorHandlerCb = null
})
-
- npmock.commands.help = (args, cb) => {
- delete npmock.commands.help
- t.equal(proc.title, 'npm')
- t.strictSame(args, ['asdf'])
- t.strictSame(npmock.argv, ['asdf'])
- t.strictSame(proc.argv, ['node', 'npm', 'asdf'])
- t.strictSame(logs, [
- 'pause',
- ['verbose', 'cli', ['node', 'npm', 'asdf']],
- ['info', 'using', 'npm@%s', '99.99.99'],
- ['info', 'using', 'node@%s', undefined],
- ])
- t.strictSame(consoleLogs, [])
- t.strictSame(errorHandlerExitCalled, null)
+ const proc = {
+ argv: ['node', 'npm', 'asdf'],
+ on: () => {},
+ }
+ npmock.argv = []
+ npmock.output = (msg) => {
+ throw new Error('test exception')
+ }
+ errorHandlerCb = () => {
+ t.match(errorHandlerCalled, /test exception/)
t.end()
}
-
cli(proc)
})
t.test('load error calls error handler', t => {
- const er = new Error('poop')
+ t.teardown(() => {
+ errorHandlerCb = null
+ LOAD_ERROR = null
+ })
+
+ const er = new Error('test load error')
LOAD_ERROR = er
const proc = {
argv: ['node', 'npm', 'asdf'],
on: () => {},
}
+ errorHandlerCb = () => {
+ t.strictSame(errorHandlerCalled, [er])
+ t.end()
+ }
cli(proc)
- t.strictSame(errorHandlerCalled, [er])
- LOAD_ERROR = null
- t.end()
})
diff --git a/deps/npm/test/lib/completion.js b/deps/npm/test/lib/completion.js
index 708f138251..c6ef901a7e 100644
--- a/deps/npm/test/lib/completion.js
+++ b/deps/npm/test/lib/completion.js
@@ -63,11 +63,14 @@ const cmdList = {
plumbing: [],
}
+// only include a subset so that the snapshots aren't huge and
+// don't change when we add/remove config definitions.
+const definitions = require('../../lib/utils/config/definitions.js')
const config = {
- types: {
- global: Boolean,
- browser: [null, Boolean, String],
- registry: [null, String],
+ definitions: {
+ global: definitions.global,
+ browser: definitions.browser,
+ registry: definitions.registry,
},
shorthands: {
reg: ['--registry'],
@@ -80,7 +83,7 @@ const deref = (cmd) => {
const Completion = requireInject('../../lib/completion.js', {
'../../lib/utils/cmd-list.js': cmdList,
- '../../lib/utils/config.js': config,
+ '../../lib/utils/config/index.js': config,
'../../lib/utils/deref-command.js': deref,
'../../lib/utils/is-windows-shell.js': false,
})
diff --git a/deps/npm/test/lib/config.js b/deps/npm/test/lib/config.js
index 3aeb29f8d3..14cd816171 100644
--- a/deps/npm/test/lib/config.js
+++ b/deps/npm/test/lib/config.js
@@ -1,4 +1,5 @@
const t = require('tap')
+
const requireInject = require('require-inject')
const { EventEmitter } = require('events')
@@ -22,12 +23,21 @@ const redactCwd = (path) => {
t.cleanSnapshot = (str) => redactCwd(str)
let result = ''
-const types = {
- 'init-author-name': String,
- 'init-version': String,
- 'init.author.name': String,
- 'init.version': String,
-}
+
+const configDefs = require('../../lib/utils/config')
+const definitions = Object.entries(configDefs.definitions)
+ .filter(([key, def]) => {
+ return [
+ 'init-author-name',
+ 'init.author.name',
+ 'init-version',
+ 'init.version',
+ ].includes(key)
+ }).reduce((defs, [key, def]) => {
+ defs[key] = def
+ return defs
+ }, {})
+
const defaults = {
'init-author-name': '',
'init-version': '1.0.0',
@@ -35,7 +45,7 @@ const defaults = {
'init.version': '1.0.0',
}
-const flatOptions = {
+const cliConfig = {
editor: 'vi',
json: false,
long: false,
@@ -43,7 +53,6 @@ const flatOptions = {
}
const npm = {
- flatOptions,
log: {
info: () => null,
enableProgress: () => null,
@@ -53,10 +62,10 @@ const npm = {
data: new Map(Object.entries({
default: { data: defaults, source: 'default values' },
global: { data: {}, source: '/etc/npmrc' },
- cli: { data: flatOptions, source: 'command line options' },
+ cli: { data: cliConfig, source: 'command line options' },
})),
get (key) {
- return flatOptions[key]
+ return cliConfig[key]
},
validate () {
return true
@@ -70,7 +79,7 @@ const npm = {
const usageUtil = () => 'usage instructions'
const mocks = {
- '../../lib/utils/config.js': { defaults, types },
+ '../../lib/utils/config/index.js': { defaults, definitions },
'../../lib/utils/usage.js': usageUtil,
}
@@ -110,13 +119,13 @@ t.test('config list overrides', t => {
},
source: '~/.npmrc',
})
- flatOptions['init.author.name'] = 'Bar'
+ cliConfig['init.author.name'] = 'Bar'
npm.config.find = () => 'cli'
result = ''
t.teardown(() => {
result = ''
npm.config.data.delete('user')
- delete flatOptions['init.author.name']
+ delete cliConfig['init.author.name']
delete npm.config.find
})
@@ -129,12 +138,12 @@ t.test('config list overrides', t => {
t.test('config list --long', t => {
t.plan(2)
- npm.config.find = key => key in flatOptions ? 'cli' : 'default'
- flatOptions.long = true
+ npm.config.find = key => key in cliConfig ? 'cli' : 'default'
+ cliConfig.long = true
result = ''
t.teardown(() => {
delete npm.config.find
- flatOptions.long = false
+ cliConfig.long = false
result = ''
})
@@ -147,7 +156,7 @@ t.test('config list --long', t => {
t.test('config list --json', t => {
t.plan(2)
- flatOptions.json = true
+ cliConfig.json = true
result = ''
npm.config.list = [{
'//private-reg.npmjs.org/:_authThoken': 'f00ba1',
@@ -158,7 +167,7 @@ t.test('config list --json', t => {
t.teardown(() => {
delete npm.config.list
- flatOptions.json = false
+ cliConfig.json = false
npm.config.get = npmConfigGet
result = ''
})
@@ -246,13 +255,13 @@ t.test('config delete key --global', t => {
t.equal(where, 'global', 'should save global config post-delete')
}
- flatOptions.global = true
+ cliConfig.global = true
config.exec(['delete', 'foo'], (err) => {
t.ifError(err, 'npm config delete key --global')
})
t.teardown(() => {
- flatOptions.global = false
+ cliConfig.global = false
delete npm.config.delete
delete npm.config.save
})
@@ -401,13 +410,13 @@ t.test('config set key --global', t => {
t.equal(where, 'global', 'should save global config')
}
- flatOptions.global = true
+ cliConfig.global = true
config.exec(['set', 'foo', 'bar'], (err) => {
t.ifError(err, 'npm config set key --global')
})
t.teardown(() => {
- flatOptions.global = false
+ cliConfig.global = false
delete npm.config.set
delete npm.config.save
})
@@ -555,7 +564,7 @@ sign-git-commit=true`
t.test('config edit --global', t => {
t.plan(6)
- flatOptions.global = true
+ cliConfig.global = true
const npmrc = 'init.author.name=Foo'
npm.config.data.set('global', {
source: '/etc/npmrc',
@@ -595,7 +604,7 @@ t.test('config edit --global', t => {
})
t.teardown(() => {
- flatOptions.global = false
+ cliConfig.global = false
npm.config.data.delete('user')
delete npm.config.save
})
@@ -612,7 +621,7 @@ t.test('completion', t => {
testComp(['npm', 'config'], ['get', 'set', 'delete', 'ls', 'rm', 'edit', 'list'])
testComp(['npm', 'config', 'set', 'foo'], [])
- const possibleConfigKeys = [...Object.keys(types)]
+ const possibleConfigKeys = [...Object.keys(definitions)]
testComp(['npm', 'config', 'get'], possibleConfigKeys)
testComp(['npm', 'config', 'set'], possibleConfigKeys)
testComp(['npm', 'config', 'delete'], possibleConfigKeys)
diff --git a/deps/npm/test/lib/dedupe.js b/deps/npm/test/lib/dedupe.js
index 3e8b2f4c01..851163f935 100644
--- a/deps/npm/test/lib/dedupe.js
+++ b/deps/npm/test/lib/dedupe.js
@@ -1,20 +1,13 @@
const { test } = require('tap')
const requireInject = require('require-inject')
-
-const npm = (base) => {
- const config = base.config
- return {
- ...base,
- flatOptions: { dryRun: false },
- config: {
- get: (k) => config[k],
- },
- }
-}
+const mockNpm = require('../fixtures/mock-npm')
test('should throw in global mode', (t) => {
const Dedupe = requireInject('../../lib/dedupe.js')
- const dedupe = new Dedupe(npm({ config: { global: true }}))
+ const npm = mockNpm({
+ config: { 'dry-run': false, global: true },
+ })
+ const dedupe = new Dedupe(npm)
dedupe.exec([], er => {
t.match(er, { code: 'EDEDUPEGLOBAL' }, 'throws EDEDUPEGLOBAL')
@@ -36,12 +29,13 @@ test('should remove dupes using Arborist', (t) => {
t.ok(arb, 'gets arborist tree')
},
})
- const dedupe = new Dedupe(npm({
+ const npm = mockNpm({
prefix: 'foo',
config: {
'dry-run': 'true',
},
- }))
+ })
+ const dedupe = new Dedupe(npm)
dedupe.exec([], er => {
if (er)
throw er
@@ -53,17 +47,18 @@ test('should remove dupes using Arborist', (t) => {
test('should remove dupes using Arborist - no arguments', (t) => {
const Dedupe = requireInject('../../lib/dedupe.js', {
'@npmcli/arborist': function (args) {
- t.ok(args.dryRun, 'gets dryRun from flatOptions')
+ t.ok(args.dryRun, 'gets dryRun from config')
this.dedupe = () => {}
},
'../../lib/utils/reify-output.js': () => {},
})
- const dedupe = new Dedupe(npm({
+ const npm = mockNpm({
prefix: 'foo',
config: {
- 'dry-run': true,
+ 'dry-run': 'true',
},
- }))
+ })
+ const dedupe = new Dedupe(npm)
dedupe.exec(null, () => {
t.end()
})
diff --git a/deps/npm/test/lib/diff.js b/deps/npm/test/lib/diff.js
index 9f58505dca..08761c64c8 100644
--- a/deps/npm/test/lib/diff.js
+++ b/deps/npm/test/lib/diff.js
@@ -1,30 +1,35 @@
const { resolve } = require('path')
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const noop = () => null
let libnpmdiff = noop
let rlp = () => 'foo'
-const defaultFlatOptions = {
- defaultTag: 'latest',
+
+const config = {
+ global: false,
+ tag: 'latest',
diff: [],
+}
+const flatOptions = {
+ global: false,
diffUnified: null,
diffIgnoreAllSpace: false,
diffNoPrefix: false,
diffSrcPrefix: '',
diffDstPrefix: '',
diffText: false,
- prefix: '.',
savePrefix: '^',
}
-const npm = {
+const npm = mockNpm({
globalDir: __dirname,
- flatOptions: { ...defaultFlatOptions },
- get prefix () {
- return this.flatOptions.prefix
- },
+ prefix: '.',
+ config,
+ flatOptions,
output: noop,
-}
+})
+
const mocks = {
npmlog: { info: noop, verbose: noop },
libnpmdiff: (...args) => libnpmdiff(...args),
@@ -34,10 +39,21 @@ const mocks = {
}
t.afterEach(cb => {
- npm.flatOptions = { ...defaultFlatOptions }
+ config.global = false
+ config.tag = 'latest'
+ config.diff = []
+ flatOptions.global = false
+ flatOptions.diffUnified = null
+ flatOptions.diffIgnoreAllSpace = false
+ flatOptions.diffNoPrefix = false
+ flatOptions.diffSrcPrefix = ''
+ flatOptions.diffDstPrefix = ''
+ flatOptions.diffText = false
+ flatOptions.savePrefix = '^'
+ npm.globalDir = __dirname
+ npm.prefix = '..'
libnpmdiff = noop
rlp = () => 'foo'
- npm.globalDir = __dirname
cb()
})
@@ -55,7 +71,7 @@ t.test('no args', t => {
t.match(opts, npm.flatOptions, 'should forward flat options')
}
- npm.flatOptions.prefix = path
+ npm.prefix = path
diff.exec([], err => {
if (err)
throw err
@@ -102,10 +118,11 @@ t.test('single arg', t => {
t.equal(a, 'foo@1.0.0', 'should forward single spec')
t.equal(b, `file:${path}`, 'should compare to cwd')
t.match(opts, npm.flatOptions, 'should forward flat options')
+ t.end()
}
- npm.flatOptions.diff = ['foo@1.0.0']
- npm.flatOptions.prefix = path
+ config.diff = ['foo@1.0.0']
+ npm.prefix = path
diff.exec([], err => {
if (err)
throw err
@@ -118,8 +135,8 @@ t.test('single arg', t => {
throw new Error('ERR')
}
- npm.flatOptions.diff = ['foo@1.0.0']
- npm.flatOptions.prefix = path
+ config.diff = ['foo@1.0.0']
+ npm.prefix = path
diff.exec([], err => {
t.match(
err,
@@ -140,8 +157,8 @@ t.test('single arg', t => {
t.match(opts, npm.flatOptions, 'should forward flat options')
}
- npm.flatOptions.diff = ['foo@~1.0.0']
- npm.flatOptions.prefix = path
+ config.diff = ['foo@~1.0.0']
+ npm.prefix = path
diff.exec([], err => {
if (err)
throw err
@@ -158,8 +175,8 @@ t.test('single arg', t => {
t.match(opts, npm.flatOptions, 'should forward flat options')
}
- npm.flatOptions.diff = ['2.1.4']
- npm.flatOptions.prefix = path
+ config.diff = ['2.1.4']
+ npm.prefix = path
diff.exec([], err => {
if (err)
throw err
@@ -171,7 +188,7 @@ t.test('single arg', t => {
throw new Error('ERR')
}
- npm.flatOptions.diff = ['2.1.4']
+ config.diff = ['2.1.4']
diff.exec([], err => {
t.match(
err,
@@ -198,8 +215,8 @@ t.test('single arg', t => {
}, 'should forward flatOptions and diffFiles')
}
- npm.flatOptions.diff = ['2.1.4']
- npm.flatOptions.prefix = path
+ config.diff = ['2.1.4']
+ npm.prefix = path
diff.exec(['./foo.js', './bar.js'], err => {
if (err)
throw err
@@ -221,8 +238,8 @@ t.test('single arg', t => {
t.equal(b, `file:${path}`, 'should compare to cwd')
}
- npm.flatOptions.diff = ['bar@1.0.0']
- npm.flatOptions.prefix = path
+ config.diff = ['bar@1.0.0']
+ npm.prefix = path
diff.exec([], err => {
if (err)
@@ -248,8 +265,8 @@ t.test('single arg', t => {
t.match(opts, npm.flatOptions, 'should forward flat options')
}
- npm.flatOptions.diff = ['simple-output']
- npm.flatOptions.prefix = path
+ config.diff = ['simple-output']
+ npm.prefix = path
diff.exec([], err => {
if (err)
throw err
@@ -262,8 +279,8 @@ t.test('single arg', t => {
throw new Error('ERR')
}
- npm.flatOptions.diff = ['bar']
- npm.flatOptions.prefix = path
+ config.diff = ['bar']
+ npm.prefix = path
diff.exec([], err => {
t.match(
err,
@@ -294,8 +311,8 @@ t.test('single arg', t => {
}),
})
- npm.flatOptions.diff = ['bar']
- npm.flatOptions.prefix = path
+ config.diff = ['bar']
+ npm.prefix = path
const Diff = requireInject('../../lib/diff.js', {
...mocks,
@@ -355,9 +372,10 @@ t.test('single arg', t => {
},
})
- npm.flatOptions.global = true
- npm.flatOptions.diff = ['lorem']
- npm.flatOptions.prefix = resolve(path, 'project')
+ config.global = true
+ flatOptions.global = true
+ config.diff = ['lorem']
+ npm.prefix = resolve(path, 'project')
npm.globalDir = resolve(path, 'globalDir/lib/node_modules')
const Diff = requireInject('../../lib/diff.js', {
@@ -409,8 +427,8 @@ t.test('single arg', t => {
t.equal(b, 'bar@2.0.0', 'should have expected comparison spec')
}
- npm.flatOptions.diff = ['bar@2.0.0']
- npm.flatOptions.prefix = path
+ config.diff = ['bar@2.0.0']
+ npm.prefix = path
diff.exec([], err => {
if (err)
@@ -466,8 +484,8 @@ t.test('single arg', t => {
})
const diff = new Diff(npm)
- npm.flatOptions.diff = ['lorem']
- npm.flatOptions.prefix = path
+ config.diff = ['lorem']
+ npm.prefix = path
diff.exec([], err => {
if (err)
@@ -499,8 +517,8 @@ t.test('single arg', t => {
})
const diff = new Diff(npm)
- npm.flatOptions.diff = ['lorem']
- npm.flatOptions.prefix = path
+ config.diff = ['lorem']
+ npm.prefix = path
diff.exec([], err => {
if (err)
@@ -518,8 +536,8 @@ t.test('single arg', t => {
t.equal(b, `file:${path}`, 'should compare to cwd')
}
- npm.flatOptions.diff = ['bar']
- npm.flatOptions.prefix = path
+ config.diff = ['bar']
+ npm.prefix = path
diff.exec([], err => {
if (err)
@@ -537,8 +555,8 @@ t.test('single arg', t => {
t.equal(b, `file:${path}`, 'should compare to cwd')
}
- npm.flatOptions.diff = ['my-project']
- npm.flatOptions.prefix = path
+ config.diff = ['my-project']
+ npm.prefix = path
diff.exec([], err => {
if (err)
throw err
@@ -555,8 +573,8 @@ t.test('single arg', t => {
t.equal(b, `file:${path}`, 'should compare to cwd')
}
- npm.flatOptions.diff = ['/path/to/other-dir']
- npm.flatOptions.prefix = path
+ config.diff = ['/path/to/other-dir']
+ npm.prefix = path
diff.exec([], err => {
if (err)
throw err
@@ -566,7 +584,7 @@ t.test('single arg', t => {
t.test('unsupported spec type', t => {
rlp = async () => 'my-project'
- npm.flatOptions.diff = ['git+https://github.com/user/foo']
+ config.diff = ['git+https://github.com/user/foo']
diff.exec([], err => {
t.match(
@@ -591,7 +609,7 @@ t.test('first arg is a qualified spec', t => {
t.match(opts, npm.flatOptions, 'should forward flat options')
}
- npm.flatOptions.diff = ['bar@1.0.0', 'bar@^2.0.0']
+ config.diff = ['bar@1.0.0', 'bar@^2.0.0']
diff.exec([], err => {
if (err)
throw err
@@ -624,8 +642,8 @@ t.test('first arg is a qualified spec', t => {
t.equal(b, `bar@file:${resolve(path, 'node_modules/bar')}`, 'should target local node_modules pkg')
}
- npm.flatOptions.prefix = path
- npm.flatOptions.diff = ['bar@2.0.0', 'bar']
+ npm.prefix = path
+ config.diff = ['bar@2.0.0', 'bar']
diff.exec([], err => {
if (err)
throw err
@@ -635,7 +653,7 @@ t.test('first arg is a qualified spec', t => {
t.test('second arg is a valid semver version', t => {
t.plan(2)
- npm.flatOptions.diff = ['bar@1.0.0', '2.0.0']
+ config.diff = ['bar@1.0.0', '2.0.0']
libnpmdiff = async ([a, b], opts) => {
t.equal(a, 'bar@1.0.0', 'should set expected first spec')
@@ -656,7 +674,7 @@ t.test('first arg is a qualified spec', t => {
t.equal(b, 'bar-fork@latest', 'should target latest tag if not a dep')
}
- npm.flatOptions.diff = ['bar@1.0.0', 'bar-fork']
+ config.diff = ['bar@1.0.0', 'bar-fork']
diff.exec([], err => {
if (err)
throw err
@@ -693,8 +711,8 @@ t.test('first arg is a known dependency name', t => {
t.equal(b, 'bar@2.0.0', 'should set expected second spec')
}
- npm.flatOptions.prefix = path
- npm.flatOptions.diff = ['bar', 'bar@2.0.0']
+ npm.prefix = path
+ config.diff = ['bar', 'bar@2.0.0']
diff.exec([], err => {
if (err)
throw err
@@ -733,8 +751,8 @@ t.test('first arg is a known dependency name', t => {
t.equal(b, `bar-fork@file:${resolve(path, 'node_modules/bar-fork')}`, 'should target fork local node_modules pkg')
}
- npm.flatOptions.prefix = path
- npm.flatOptions.diff = ['bar', 'bar-fork']
+ npm.prefix = path
+ config.diff = ['bar', 'bar-fork']
diff.exec([], err => {
if (err)
throw err
@@ -767,8 +785,8 @@ t.test('first arg is a known dependency name', t => {
t.equal(b, 'bar@2.0.0', 'should use package name from first arg')
}
- npm.flatOptions.prefix = path
- npm.flatOptions.diff = ['bar', '2.0.0']
+ npm.prefix = path
+ config.diff = ['bar', '2.0.0']
diff.exec([], err => {
if (err)
throw err
@@ -801,8 +819,8 @@ t.test('first arg is a known dependency name', t => {
t.equal(b, 'bar-fork@latest', 'should set expected second spec')
}
- npm.flatOptions.prefix = path
- npm.flatOptions.diff = ['bar', 'bar-fork']
+ npm.prefix = path
+ config.diff = ['bar', 'bar-fork']
diff.exec([], err => {
if (err)
throw err
@@ -816,7 +834,7 @@ t.test('first arg is a valid semver range', t => {
t.test('second arg is a qualified spec', t => {
t.plan(2)
- npm.flatOptions.diff = ['1.0.0', 'bar@2.0.0']
+ config.diff = ['1.0.0', 'bar@2.0.0']
libnpmdiff = async ([a, b], opts) => {
t.equal(a, 'bar@1.0.0', 'should use name from second arg')
@@ -855,8 +873,8 @@ t.test('first arg is a valid semver range', t => {
t.equal(b, `bar@file:${resolve(path, 'node_modules/bar')}`, 'should set expected second spec from nm')
}
- npm.flatOptions.prefix = path
- npm.flatOptions.diff = ['1.0.0', 'bar']
+ npm.prefix = path
+ config.diff = ['1.0.0', 'bar']
diff.exec([], err => {
if (err)
throw err
@@ -872,7 +890,7 @@ t.test('first arg is a valid semver range', t => {
t.equal(b, 'my-project@2.0.0', 'should use name from project dir')
}
- npm.flatOptions.diff = ['1.0.0', '2.0.0']
+ config.diff = ['1.0.0', '2.0.0']
diff.exec([], err => {
if (err)
throw err
@@ -885,8 +903,8 @@ t.test('first arg is a valid semver range', t => {
throw new Error('ERR')
}
- npm.flatOptions.diff = ['1.0.0', '2.0.0']
- npm.flatOptions.prefix = path
+ config.diff = ['1.0.0', '2.0.0']
+ npm.prefix = path
diff.exec([], err => {
t.match(
err,
@@ -906,7 +924,7 @@ t.test('first arg is a valid semver range', t => {
t.equal(b, 'bar@latest', 'should compare against latest tag')
}
- npm.flatOptions.diff = ['1.0.0', 'bar']
+ config.diff = ['1.0.0', 'bar']
diff.exec([], err => {
if (err)
throw err
@@ -937,8 +955,8 @@ t.test('first arg is a valid semver range', t => {
})
const diff = new Diff(npm)
- npm.flatOptions.diff = ['1.0.0', 'lorem@2.0.0']
- npm.flatOptions.prefix = path
+ config.diff = ['1.0.0', 'lorem@2.0.0']
+ npm.prefix = path
diff.exec([], err => {
if (err)
@@ -960,7 +978,7 @@ t.test('first arg is an unknown dependency name', t => {
t.match(opts, { where: '.' }, 'should forward pacote options')
}
- npm.flatOptions.diff = ['bar', 'bar@2.0.0']
+ config.diff = ['bar', 'bar@2.0.0']
diff.exec([], err => {
if (err)
throw err
@@ -993,8 +1011,8 @@ t.test('first arg is an unknown dependency name', t => {
t.equal(b, `bar@file:${resolve(path, 'node_modules/bar')}`, 'should target local node_modules pkg')
}
- npm.flatOptions.prefix = path
- npm.flatOptions.diff = ['bar-fork', 'bar']
+ npm.prefix = path
+ config.diff = ['bar-fork', 'bar']
diff.exec([], err => {
if (err)
throw err
@@ -1009,7 +1027,7 @@ t.test('first arg is an unknown dependency name', t => {
t.equal(b, 'bar@^1.0.0', 'should use name from first arg')
}
- npm.flatOptions.diff = ['bar', '^1.0.0']
+ config.diff = ['bar', '^1.0.0']
diff.exec([], err => {
if (err)
throw err
@@ -1024,7 +1042,7 @@ t.test('first arg is an unknown dependency name', t => {
t.equal(b, 'bar-fork@latest', 'should use latest tag')
}
- npm.flatOptions.diff = ['bar', 'bar-fork']
+ config.diff = ['bar', 'bar-fork']
diff.exec([], err => {
if (err)
throw err
@@ -1043,8 +1061,8 @@ t.test('first arg is an unknown dependency name', t => {
t.equal(b, 'bar-fork@latest', 'should use latest tag')
}
- npm.flatOptions.diff = ['bar', 'bar-fork']
- npm.flatOptions.prefix = path
+ config.diff = ['bar', 'bar-fork']
+ npm.prefix = path
diff.exec([], err => {
if (err)
@@ -1059,7 +1077,7 @@ t.test('various options', t => {
t.test('using --name-only option', t => {
t.plan(1)
- npm.flatOptions.diffNameOnly = true
+ flatOptions.diffNameOnly = true
libnpmdiff = async ([a, b], opts) => {
t.match(opts, {
@@ -1077,7 +1095,7 @@ t.test('various options', t => {
t.test('set files after both versions', t => {
t.plan(3)
- npm.flatOptions.diff = ['2.1.4', '3.0.0']
+ config.diff = ['2.1.4', '3.0.0']
libnpmdiff = async ([a, b], opts) => {
t.equal(a, 'foo@2.1.4', 'should use expected spec')
@@ -1114,7 +1132,7 @@ t.test('various options', t => {
}, 'should forward all remaining items as filenames')
}
- npm.flatOptions.prefix = path
+ npm.prefix = path
diff.exec(['./foo.js', './bar.js'], err => {
if (err)
throw err
@@ -1124,12 +1142,12 @@ t.test('various options', t => {
t.test('using diff option', t => {
t.plan(1)
- npm.flatOptions.diffContext = 5
- npm.flatOptions.diffIgnoreWhitespace = true
- npm.flatOptions.diffNoPrefix = false
- npm.flatOptions.diffSrcPrefix = 'foo/'
- npm.flatOptions.diffDstPrefix = 'bar/'
- npm.flatOptions.diffText = true
+ flatOptions.diffContext = 5
+ flatOptions.diffIgnoreWhitespace = true
+ flatOptions.diffNoPrefix = false
+ flatOptions.diffSrcPrefix = 'foo/'
+ flatOptions.diffDstPrefix = 'bar/'
+ flatOptions.diffText = true
libnpmdiff = async ([a, b], opts) => {
t.match(opts, {
@@ -1153,7 +1171,7 @@ t.test('various options', t => {
})
t.test('too many args', t => {
- npm.flatOptions.diff = ['a', 'b', 'c']
+ config.diff = ['a', 'b', 'c']
diff.exec([], err => {
t.match(
err,
diff --git a/deps/npm/test/lib/dist-tag.js b/deps/npm/test/lib/dist-tag.js
index a3c05bb2b3..9415dacbe4 100644
--- a/deps/npm/test/lib/dist-tag.js
+++ b/deps/npm/test/lib/dist-tag.js
@@ -1,18 +1,10 @@
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const { test } = require('tap')
-let prefix
let result = ''
let log = ''
-// these declared opts are used in ./utils/read-local-package.js
-const _flatOptions = {
- global: false,
- get prefix () {
- return prefix
- },
-}
-
const routeMap = {
'/-/package/@scoped%2fpkg/dist-tags': {
latest: '1.0.0',
@@ -60,20 +52,18 @@ const DistTag = requireInject('../../lib/dist-tag.js', {
},
})
-const distTag = new DistTag({
- flatOptions: _flatOptions,
+const npm = mockNpm({
config: {
- get (key) {
- return _flatOptions[key]
- },
+ global: false,
},
output: msg => {
result = msg
},
})
+const distTag = new DistTag(npm)
test('ls in current package', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: '@scoped/pkg',
}),
@@ -91,7 +81,7 @@ test('ls in current package', (t) => {
})
test('no args in current package', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: '@scoped/pkg',
}),
@@ -109,7 +99,7 @@ test('no args in current package', (t) => {
})
test('borked cmd usage', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
distTag.exec(['borked', '@scoped/pkg'], (err) => {
t.matchSnapshot(err, 'should show usage error')
result = ''
@@ -119,7 +109,7 @@ test('borked cmd usage', (t) => {
})
test('ls on named package', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
distTag.exec(['ls', '@scoped/another'], (err) => {
t.ifError(err, 'npm dist-tags ls')
t.matchSnapshot(
@@ -133,7 +123,7 @@ test('ls on named package', (t) => {
})
test('ls on missing package', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
distTag.exec(['ls', 'foo'], (err) => {
t.matchSnapshot(
log,
@@ -150,7 +140,7 @@ test('ls on missing package', (t) => {
})
test('ls on missing name in current package', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
version: '1.0.0',
}),
@@ -167,7 +157,7 @@ test('ls on missing name in current package', (t) => {
})
test('only named package arg', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
distTag.exec(['@scoped/another'], (err) => {
t.ifError(err, 'npm dist-tags ls')
t.matchSnapshot(
@@ -186,7 +176,7 @@ test('add new tag', (t) => {
t.equal(opts.method, 'PUT', 'should trigger request to add new tag')
t.equal(opts.body, '7.7.7', 'should point to expected version')
}
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
distTag.exec(['add', '@scoped/another@7.7.7', 'c'], (err) => {
t.ifError(err, 'npm dist-tags add')
t.matchSnapshot(
@@ -201,7 +191,7 @@ test('add new tag', (t) => {
})
test('add using valid semver range as name', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
distTag.exec(['add', '@scoped/another@7.7.7', '1.0.0'], (err) => {
t.match(
err,
@@ -219,7 +209,7 @@ test('add using valid semver range as name', (t) => {
})
test('add missing args', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
distTag.exec(['add', '@scoped/another@7.7.7'], (err) => {
t.matchSnapshot(err, 'should exit usage error message')
result = ''
@@ -229,7 +219,7 @@ test('add missing args', (t) => {
})
test('add missing pkg name', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
distTag.exec(['add', null], (err) => {
t.matchSnapshot(err, 'should exit usage error message')
result = ''
@@ -239,7 +229,7 @@ test('add missing pkg name', (t) => {
})
test('set existing version', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
distTag.exec(['set', '@scoped/another@0.6.0', 'b'], (err) => {
t.ifError(err, 'npm dist-tags set')
t.matchSnapshot(
@@ -256,7 +246,7 @@ test('remove existing tag', (t) => {
npmRegistryFetchMock = async (url, opts) => {
t.equal(opts.method, 'DELETE', 'should trigger request to remove tag')
}
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
distTag.exec(['rm', '@scoped/another', 'c'], (err) => {
t.ifError(err, 'npm dist-tags rm')
t.matchSnapshot(log, 'should log remove info')
@@ -269,7 +259,7 @@ test('remove existing tag', (t) => {
})
test('remove non-existing tag', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
distTag.exec(['rm', '@scoped/another', 'nonexistent'], (err) => {
t.match(
err,
@@ -284,7 +274,7 @@ test('remove non-existing tag', (t) => {
})
test('remove missing pkg name', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
distTag.exec(['rm', null], (err) => {
t.matchSnapshot(err, 'should exit usage error message')
result = ''
diff --git a/deps/npm/test/lib/exec.js b/deps/npm/test/lib/exec.js
index eb9fef6a61..bcfe75577c 100644
--- a/deps/npm/test/lib/exec.js
+++ b/deps/npm/test/lib/exec.js
@@ -1,5 +1,6 @@
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const { resolve, delimiter } = require('path')
const OUTPUT = []
const output = (...msg) => OUTPUT.push(msg)
@@ -25,25 +26,23 @@ class Arborist {
let PROGRESS_ENABLED = true
const LOG_WARN = []
let PROGRESS_IGNORED = false
-const npm = {
- flatOptions: {
- yes: true,
- call: '',
- package: [],
- legacyPeerDeps: false,
- shell: 'shell-cmd',
- },
+const flatOptions = {
+ legacyPeerDeps: false,
+ package: [],
+}
+const config = {
+ cache: 'cache-dir',
+ yes: true,
+ call: '',
+ package: [],
+ shell: 'shell-cmd',
+}
+const npm = mockNpm({
+ flatOptions,
+ config,
localPrefix: 'local-prefix',
localBin: 'local-bin',
globalBin: 'global-bin',
- config: {
- get: k => {
- if (k !== 'cache')
- throw new Error('unexpected config get')
-
- return 'cache-dir'
- },
- },
log: {
disableProgress: () => {
PROGRESS_ENABLED = false
@@ -56,7 +55,7 @@ const npm = {
},
},
output,
-}
+})
const RUN_SCRIPTS = []
const runScript = async opt => {
@@ -108,9 +107,12 @@ t.afterEach(cb => {
READ_ERROR = null
LOG_WARN.length = 0
PROGRESS_IGNORED = false
- npm.flatOptions.legacyPeerDeps = false
- npm.flatOptions.package = []
- npm.flatOptions.call = ''
+ flatOptions.legacyPeerDeps = false
+ config.color = false
+ config.package = []
+ flatOptions.package = []
+ config.call = ''
+ config.yes = true
npm.localBin = 'local-bin'
npm.globalBin = 'global-bin'
cb()
@@ -186,7 +188,7 @@ t.test('npm exec foo, already present locally', t => {
if (er)
throw er
t.strictSame(MKDIRPS, [], 'no need to make any dirs')
- t.match(ARB_CTOR, [{ package: ['foo'], path }])
+ t.match(ARB_CTOR, [{ path }])
t.strictSame(ARB_REIFY, [], 'no need to reify anything')
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled')
t.match(RUN_SCRIPTS, [{
@@ -240,14 +242,27 @@ t.test('npm exec <noargs>, run interactive shell', t => {
cb()
})
}
-
t.test('print message when tty and not in CI', t => {
CI_NAME = null
process.stdin.isTTY = true
run(t, true, () => {
t.strictSame(LOG_WARN, [])
t.strictSame(OUTPUT, [
- ['\nEntering npm script environment\nType \'exit\' or ^D when finished\n'],
+ [`\nEntering npm script environment at location:\n${process.cwd()}\nType 'exit' or ^D when finished\n`],
+ ], 'printed message about interactive shell')
+ t.end()
+ })
+ })
+
+ t.test('print message with color when tty and not in CI', t => {
+ CI_NAME = null
+ process.stdin.isTTY = true
+ config.color = true
+
+ run(t, true, () => {
+ t.strictSame(LOG_WARN, [])
+ t.strictSame(OUTPUT, [
+ [`\u001b[0m\u001b[0m\n\u001b[0mEntering npm script environment\u001b[0m\u001b[0m at location:\u001b[0m\n\u001b[0m\u001b[2m${process.cwd()}\u001b[22m\u001b[0m\u001b[1m\u001b[22m\n\u001b[1mType 'exit' or ^D when finished\u001b[22m\n\u001b[1m\u001b[22m`],
], 'printed message about interactive shell')
t.end()
})
@@ -300,7 +315,7 @@ t.test('npm exec foo, not present locally or in central loc', t => {
if (er)
throw er
t.strictSame(MKDIRPS, [installDir], 'need to make install dir')
- t.match(ARB_CTOR, [{ package: ['foo'], path }])
+ t.match(ARB_CTOR, [{ 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}`
@@ -340,7 +355,7 @@ t.test('npm exec foo, not present locally but in central loc', t => {
if (er)
throw er
t.strictSame(MKDIRPS, [installDir], 'need to make install dir')
- t.match(ARB_CTOR, [{ package: ['foo'], path }])
+ t.match(ARB_CTOR, [{ 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}`
@@ -380,7 +395,7 @@ t.test('npm exec foo, present locally but wrong version', t => {
if (er)
throw er
t.strictSame(MKDIRPS, [installDir], 'need to make install dir')
- t.match(ARB_CTOR, [{ package: ['foo'], path }])
+ t.match(ARB_CTOR, [{ 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}`
@@ -412,12 +427,13 @@ t.test('npm exec --package=foo bar', t => {
},
_from: 'foo@',
}
- npm.flatOptions.package = ['foo']
+ config.package = ['foo']
+ flatOptions.package = ['foo']
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.match(ARB_CTOR, [{ path }])
t.strictSame(ARB_REIFY, [], 'no need to reify anything')
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled')
t.match(RUN_SCRIPTS, [{
@@ -459,7 +475,7 @@ t.test('npm exec @foo/bar -- --some=arg, locally installed', t => {
if (er)
throw er
t.strictSame(MKDIRPS, [], 'no need to make any dirs')
- t.match(ARB_CTOR, [{ package: ['@foo/bar'], path }])
+ t.match(ARB_CTOR, [{ path }])
t.strictSame(ARB_REIFY, [], 'no need to reify anything')
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled')
t.match(RUN_SCRIPTS, [{
@@ -502,7 +518,7 @@ t.test('npm exec @foo/bar, with same bin alias and no unscoped named bin, locall
if (er)
throw er
t.strictSame(MKDIRPS, [], 'no need to make any dirs')
- t.match(ARB_CTOR, [{ package: ['@foo/bar'], path }])
+ t.match(ARB_CTOR, [{ path }])
t.strictSame(ARB_REIFY, [], 'no need to reify anything')
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled')
t.match(RUN_SCRIPTS, [{
@@ -552,7 +568,7 @@ t.test('run command with 2 packages, need install, verify sort', t => {
t.plan(cases.length)
for (const packages of cases) {
t.test(packages.join(', '), t => {
- npm.flatOptions.package = packages
+ config.package = packages
const add = packages.map(p => `${p}@`).sort((a, b) => a.localeCompare(b))
const path = t.testdir()
const installDir = resolve('cache-dir/_npx/07de77790e5f40f2')
@@ -583,7 +599,7 @@ t.test('run command with 2 packages, need install, verify sort', t => {
if (er)
throw er
t.strictSame(MKDIRPS, [installDir], 'need to make install dir')
- t.match(ARB_CTOR, [{ package: packages, path }])
+ t.match(ARB_CTOR, [{ 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}`
@@ -652,8 +668,8 @@ t.test('npm exec foo, many bins in package, none named foo', t => {
t.test('npm exec -p foo -c "ls -laF"', t => {
const path = t.testdir()
npm.localPrefix = path
- npm.flatOptions.package = ['foo']
- npm.flatOptions.call = 'ls -laF'
+ config.package = ['foo']
+ config.call = 'ls -laF'
ARB_ACTUAL_TREE[path] = {
children: new Map([['foo', { name: 'foo', version: '1.2.3' }]]),
}
@@ -666,7 +682,7 @@ t.test('npm exec -p foo -c "ls -laF"', t => {
if (er)
throw er
t.strictSame(MKDIRPS, [], 'no need to make any dirs')
- t.match(ARB_CTOR, [{ package: ['foo'], path }])
+ t.match(ARB_CTOR, [{ path }])
t.strictSame(ARB_REIFY, [], 'no need to reify anything')
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled')
t.match(RUN_SCRIPTS, [{
@@ -683,7 +699,7 @@ t.test('npm exec -p foo -c "ls -laF"', t => {
})
t.test('positional args and --call together is an error', t => {
- npm.flatOptions.call = 'true'
+ config.call = 'true'
exec.exec(['foo'], er => {
t.equal(er, exec.usage)
t.end()
@@ -705,8 +721,8 @@ t.test('prompt when installs are needed if not already present and shell is a TT
const packages = ['foo', 'bar']
READ_RESULT = 'yolo'
- npm.flatOptions.package = packages
- npm.flatOptions.yes = undefined
+ config.package = packages
+ config.yes = undefined
const add = packages.map(p => `${p}@`).sort((a, b) => a.localeCompare(b))
const path = t.testdir()
@@ -738,7 +754,7 @@ t.test('prompt when installs are needed if not already present and shell is a TT
if (er)
throw er
t.strictSame(MKDIRPS, [installDir], 'need to make install dir')
- t.match(ARB_CTOR, [{ package: packages, path }])
+ t.match(ARB_CTOR, [{ 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}`
@@ -774,8 +790,8 @@ t.test('skip prompt when installs are needed if not already present and shell is
const packages = ['foo', 'bar']
READ_RESULT = 'yolo'
- npm.flatOptions.package = packages
- npm.flatOptions.yes = undefined
+ config.package = packages
+ config.yes = undefined
const add = packages.map(p => `${p}@`).sort((a, b) => a.localeCompare(b))
const path = t.testdir()
@@ -807,7 +823,7 @@ t.test('skip prompt when installs are needed if not already present and shell is
if (er)
throw er
t.strictSame(MKDIRPS, [installDir], 'need to make install dir')
- t.match(ARB_CTOR, [{ package: packages, path }])
+ t.match(ARB_CTOR, [{ 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}`
@@ -841,8 +857,8 @@ t.test('skip prompt when installs are needed if not already present and shell is
const packages = ['foo']
READ_RESULT = 'yolo'
- npm.flatOptions.package = packages
- npm.flatOptions.yes = undefined
+ config.package = packages
+ config.yes = undefined
const add = packages.map(p => `${p}@`).sort((a, b) => a.localeCompare(b))
const path = t.testdir()
@@ -866,7 +882,7 @@ t.test('skip prompt when installs are needed if not already present and shell is
if (er)
throw er
t.strictSame(MKDIRPS, [installDir], 'need to make install dir')
- t.match(ARB_CTOR, [{ package: packages, path }])
+ t.match(ARB_CTOR, [{ 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}`
@@ -900,8 +916,8 @@ t.test('abort if prompt rejected', t => {
const packages = ['foo', 'bar']
READ_RESULT = 'no, why would I want such a thing??'
- npm.flatOptions.package = packages
- npm.flatOptions.yes = undefined
+ config.package = packages
+ config.yes = undefined
const path = t.testdir()
const installDir = resolve('cache-dir/_npx/07de77790e5f40f2')
@@ -929,9 +945,9 @@ t.test('abort if prompt rejected', t => {
_from: 'bar@',
}
exec.exec(['foobar'], er => {
- t.equal(er, 'canceled', 'should be canceled')
+ t.match(er, /canceled/, 'should be canceled')
t.strictSame(MKDIRPS, [installDir], 'need to make install dir')
- t.match(ARB_CTOR, [{ package: packages, path }])
+ t.match(ARB_CTOR, [{ path }])
t.strictSame(ARB_REIFY, [], 'no install performed')
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled')
t.strictSame(RUN_SCRIPTS, [])
@@ -958,8 +974,8 @@ t.test('abort if prompt false', t => {
const packages = ['foo', 'bar']
READ_ERROR = 'canceled'
- npm.flatOptions.package = packages
- npm.flatOptions.yes = undefined
+ config.package = packages
+ config.yes = undefined
const path = t.testdir()
const installDir = resolve('cache-dir/_npx/07de77790e5f40f2')
@@ -989,7 +1005,7 @@ t.test('abort if prompt false', t => {
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.match(ARB_CTOR, [{ path }])
t.strictSame(ARB_REIFY, [], 'no install performed')
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled')
t.strictSame(RUN_SCRIPTS, [])
@@ -1015,8 +1031,8 @@ t.test('abort if -n provided', t => {
const packages = ['foo', 'bar']
- npm.flatOptions.package = packages
- npm.flatOptions.yes = false
+ config.package = packages
+ config.yes = false
const path = t.testdir()
const installDir = resolve('cache-dir/_npx/07de77790e5f40f2')
@@ -1044,9 +1060,9 @@ t.test('abort if -n provided', t => {
_from: 'bar@',
}
exec.exec(['foobar'], er => {
- t.equal(er, 'canceled', 'should be canceled')
+ t.match(er, /canceled/, 'should be canceled')
t.strictSame(MKDIRPS, [installDir], 'need to make install dir')
- t.match(ARB_CTOR, [{ package: packages, path }])
+ t.match(ARB_CTOR, [{ path }])
t.strictSame(ARB_REIFY, [], 'no install performed')
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled')
t.strictSame(RUN_SCRIPTS, [])
@@ -1073,8 +1089,8 @@ t.test('forward legacyPeerDeps opt', t => {
},
_from: 'foo@',
}
- npm.flatOptions.yes = true
- npm.flatOptions.legacyPeerDeps = true
+ config.yes = true
+ flatOptions.legacyPeerDeps = true
exec.exec(['foo'], er => {
if (er)
throw er
@@ -1082,3 +1098,93 @@ t.test('forward legacyPeerDeps opt', t => {
t.done()
})
})
+
+t.test('workspaces', t => {
+ npm.localPrefix = t.testdir({
+ node_modules: {
+ '.bin': {
+ foo: '',
+ },
+ },
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ bin: 'cli.js',
+ }),
+ 'cli.js': '',
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ }),
+ },
+ },
+ 'package.json': JSON.stringify({
+ name: 'root',
+ version: '1.0.0',
+ workspaces: ['packages/*'],
+ }),
+ })
+
+ PROGRESS_IGNORED = true
+ npm.localBin = resolve(npm.localPrefix, 'node_modules/.bin')
+
+ t.test('with args, run scripts in the context of a workspace', t => {
+ exec.execWorkspaces(['foo', 'one arg', 'two arg'], ['a', 'b'], er => {
+ if (er)
+ throw er
+
+ t.match(RUN_SCRIPTS, [{
+ pkg: { scripts: { npx: 'foo' }},
+ args: ['one arg', 'two arg'],
+ banner: false,
+ path: process.cwd(),
+ stdioString: true,
+ event: 'npx',
+ env: {
+ PATH: [npm.localBin, ...PATH].join(delimiter),
+ },
+ stdio: 'inherit',
+ }])
+ t.end()
+ })
+ })
+
+ t.test('no args, spawn interactive shell', async t => {
+ CI_NAME = null
+ process.stdin.isTTY = true
+
+ await new Promise((res, rej) => {
+ exec.execWorkspaces([], ['a'], er => {
+ if (er)
+ return rej(er)
+
+ t.strictSame(LOG_WARN, [])
+ t.strictSame(OUTPUT, [
+ [`\nEntering npm script environment in workspace a@1.0.0 at location:\n${resolve(npm.localPrefix, 'packages/a')}\nType 'exit' or ^D when finished\n`],
+ ], 'printed message about interactive shell')
+ res()
+ })
+ })
+
+ config.color = true
+ OUTPUT.length = 0
+ await new Promise((res, rej) => {
+ exec.execWorkspaces([], ['a'], er => {
+ if (er)
+ return rej(er)
+
+ t.strictSame(LOG_WARN, [])
+ t.strictSame(OUTPUT, [
+ [`\u001b[0m\u001b[0m\n\u001b[0mEntering npm script environment\u001b[0m\u001b[0m in workspace \u001b[32ma@1.0.0\u001b[39m at location:\u001b[0m\n\u001b[0m\u001b[2m${resolve(npm.localPrefix, 'packages/a')}\u001b[22m\u001b[0m\u001b[1m\u001b[22m\n\u001b[1mType 'exit' or ^D when finished\u001b[22m\n\u001b[1m\u001b[22m`],
+ ], 'printed message about interactive shell')
+ res()
+ })
+ })
+ })
+
+ t.end()
+})
diff --git a/deps/npm/test/lib/fund.js b/deps/npm/test/lib/fund.js
index 2ae604a653..8c10007844 100644
--- a/deps/npm/test/lib/fund.js
+++ b/deps/npm/test/lib/fund.js
@@ -1,5 +1,6 @@
const { test } = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const version = '1.0.0'
const funding = {
@@ -180,19 +181,18 @@ const conflictingFundingPackages = {
let result = ''
let printUrl = ''
-const _flatOptions = {
+const config = {
color: false,
json: false,
global: false,
- prefix: undefined,
unicode: false,
- which: undefined,
+ which: null,
}
const openUrl = async (npm, url, msg) => {
if (url === 'http://npmjs.org')
throw new Error('ERROR')
- if (_flatOptions.json) {
+ if (config.json) {
printUrl = JSON.stringify({
title: msg,
url: url,
@@ -210,18 +210,16 @@ const Fund = requireInject('../../lib/fund.js', {
: Promise.reject(new Error('ERROR')),
},
})
-const fund = new Fund({
- flatOptions: _flatOptions,
- get prefix () {
- return _flatOptions.prefix
- },
+const npm = mockNpm({
+ config,
output: msg => {
result += msg + '\n'
},
})
+const fund = new Fund(npm)
test('fund with no package containing funding', t => {
- _flatOptions.prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'no-funding-package',
version: '0.0.0',
@@ -237,7 +235,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)
+ npm.prefix = t.testdir(maintainerOwnsAllDeps)
fund.exec([], (err) => {
t.ifError(err, 'should not error out')
@@ -248,8 +246,8 @@ test('fund in which same maintainer owns all its deps', t => {
})
test('fund in which same maintainer owns all its deps, using --json option', t => {
- _flatOptions.json = true
- _flatOptions.prefix = t.testdir(maintainerOwnsAllDeps)
+ config.json = true
+ npm.prefix = t.testdir(maintainerOwnsAllDeps)
fund.exec([], (err) => {
t.ifError(err, 'should not error out')
@@ -281,13 +279,13 @@ test('fund in which same maintainer owns all its deps, using --json option', t =
)
result = ''
- _flatOptions.json = false
+ config.json = false
t.end()
})
})
test('fund containing multi-level nested deps with no funding', t => {
- _flatOptions.prefix = t.testdir(nestedNoFundingPackages)
+ npm.prefix = t.testdir(nestedNoFundingPackages)
fund.exec([], (err) => {
t.ifError(err, 'should not error out')
@@ -302,8 +300,8 @@ test('fund containing multi-level nested deps with no funding', t => {
})
test('fund containing multi-level nested deps with no funding, using --json option', t => {
- _flatOptions.prefix = t.testdir(nestedNoFundingPackages)
- _flatOptions.json = true
+ npm.prefix = t.testdir(nestedNoFundingPackages)
+ config.json = true
fund.exec([], (err) => {
t.ifError(err, 'should not error out')
@@ -328,14 +326,14 @@ test('fund containing multi-level nested deps with no funding, using --json opti
)
result = ''
- _flatOptions.json = false
+ config.json = false
t.end()
})
})
test('fund containing multi-level nested deps with no funding, using --json option', t => {
- _flatOptions.prefix = t.testdir(nestedMultipleFundingPackages)
- _flatOptions.json = true
+ npm.prefix = t.testdir(nestedMultipleFundingPackages)
+ config.json = true
fund.exec([], (err) => {
t.ifError(err, 'should not error out')
@@ -385,26 +383,26 @@ test('fund containing multi-level nested deps with no funding, using --json opti
)
result = ''
- _flatOptions.json = false
+ config.json = false
t.end()
})
})
test('fund does not support global', t => {
- _flatOptions.prefix = t.testdir({})
- _flatOptions.global = true
+ npm.prefix = t.testdir({})
+ config.global = true
fund.exec([], (err) => {
t.match(err.code, 'EFUNDGLOBAL', 'should throw EFUNDGLOBAL error')
result = ''
- _flatOptions.global = false
+ config.global = false
t.end()
})
})
test('fund using package argument', t => {
- _flatOptions.prefix = t.testdir(maintainerOwnsAllDeps)
+ npm.prefix = t.testdir(maintainerOwnsAllDeps)
fund.exec(['.'], (err) => {
t.ifError(err, 'should not error out')
@@ -416,9 +414,9 @@ test('fund using package argument', t => {
})
test('fund does not support global, using --json option', t => {
- _flatOptions.prefix = t.testdir({})
- _flatOptions.global = true
- _flatOptions.json = true
+ npm.prefix = t.testdir({})
+ config.global = true
+ config.json = true
fund.exec([], (err) => {
t.equal(err.code, 'EFUNDGLOBAL', 'should use EFUNDGLOBAL error code')
@@ -428,14 +426,14 @@ test('fund does not support global, using --json option', t => {
'should use expected error msg'
)
- _flatOptions.global = false
- _flatOptions.json = false
+ config.global = false
+ config.json = false
t.end()
})
})
test('fund using string shorthand', t => {
- _flatOptions.prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'funding-string-shorthand',
version: '0.0.0',
@@ -453,7 +451,7 @@ test('fund using string shorthand', t => {
})
test('fund using nested packages with multiple sources', t => {
- _flatOptions.prefix = t.testdir(nestedMultipleFundingPackages)
+ npm.prefix = t.testdir(nestedMultipleFundingPackages)
fund.exec(['.'], (err) => {
t.ifError(err, 'should not error out')
@@ -465,7 +463,7 @@ test('fund using nested packages with multiple sources', t => {
})
test('fund using symlink ref', t => {
- _flatOptions.prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'using-symlink-ref',
version: '1.0.0',
@@ -511,7 +509,7 @@ test('fund using symlink ref', t => {
})
test('fund using data from actual tree', t => {
- _flatOptions.prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'using-actual-tree',
version: '1.0.0',
@@ -558,22 +556,22 @@ test('fund using data from actual tree', t => {
})
test('fund using nested packages with multiple sources, with a source number', t => {
- _flatOptions.prefix = t.testdir(nestedMultipleFundingPackages)
- _flatOptions.which = '1'
+ npm.prefix = t.testdir(nestedMultipleFundingPackages)
+ config.which = '1'
fund.exec(['.'], (err) => {
t.ifError(err, 'should not error out')
t.matchSnapshot(printUrl, 'should open the numbered URL')
- _flatOptions.which = undefined
+ config.which = null
printUrl = ''
t.end()
})
})
test('fund using pkg name while having conflicting versions', t => {
- _flatOptions.prefix = t.testdir(conflictingFundingPackages)
- _flatOptions.which = '1'
+ npm.prefix = t.testdir(conflictingFundingPackages)
+ config.which = '1'
fund.exec(['foo'], (err) => {
t.ifError(err, 'should not error out')
@@ -585,8 +583,8 @@ test('fund using pkg name while having conflicting versions', t => {
})
test('fund using package argument with no browser, using --json option', t => {
- _flatOptions.prefix = t.testdir(maintainerOwnsAllDeps)
- _flatOptions.json = true
+ npm.prefix = t.testdir(maintainerOwnsAllDeps)
+ config.json = true
fund.exec(['.'], (err) => {
t.ifError(err, 'should not error out')
@@ -599,14 +597,14 @@ test('fund using package argument with no browser, using --json option', t => {
'should open funding url using json output'
)
- _flatOptions.json = false
+ config.json = false
printUrl = ''
t.end()
})
})
test('fund using package info fetch from registry', t => {
- _flatOptions.prefix = t.testdir({})
+ npm.prefix = t.testdir({})
fund.exec(['ntl'], (err) => {
t.ifError(err, 'should not error out')
@@ -622,7 +620,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({})
+ npm.prefix = t.testdir({})
fund.exec(['foo'], (err) => {
t.equal(err.code, 'ENOFUND', 'should have ENOFUND error code')
@@ -638,7 +636,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)
+ npm.prefix = t.testdir(nestedNoFundingPackages)
fund.exec(['foo'], (err) => {
t.equal(err.code, 'ENOFUND', 'should have ENOFUND error code')
@@ -654,8 +652,8 @@ test('fund but target module has no funding info', t => {
})
test('fund using bad which value', t => {
- _flatOptions.prefix = t.testdir(nestedMultipleFundingPackages)
- _flatOptions.which = 3
+ npm.prefix = t.testdir(nestedMultipleFundingPackages)
+ config.which = 3
fund.exec(['bar'], (err) => {
t.equal(err.code, 'EFUNDNUMBER', 'should have EFUNDNUMBER error code')
@@ -665,14 +663,14 @@ test('fund using bad which value', t => {
'should have bad which option error message'
)
- _flatOptions.which = undefined
+ config.which = null
result = ''
t.end()
})
})
test('fund pkg missing version number', t => {
- _flatOptions.prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'foo',
funding: 'http://example.com/foo',
@@ -688,7 +686,7 @@ test('fund pkg missing version number', t => {
})
test('fund a package throws on openUrl', t => {
- _flatOptions.prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'foo',
version: '1.0.0',
@@ -704,7 +702,7 @@ test('fund a package throws on openUrl', t => {
})
test('fund a package with type and multiple sources', t => {
- _flatOptions.prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'foo',
funding: [
@@ -730,7 +728,7 @@ test('fund a package with type and multiple sources', t => {
})
test('fund colors', t => {
- _flatOptions.prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-fund-colors',
version: '1.0.0',
@@ -782,20 +780,20 @@ test('fund colors', t => {
},
},
})
- _flatOptions.color = true
+ npm.color = true
fund.exec([], (err) => {
t.ifError(err, 'should not error out')
t.matchSnapshot(result, 'should print output with color info')
result = ''
- _flatOptions.color = false
+ npm.color = false
t.end()
})
})
test('sub dep with fund info and a parent with no funding info', t => {
- _flatOptions.prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-multiple-funding-sources',
version: '1.0.0',
diff --git a/deps/npm/test/lib/help-search.js b/deps/npm/test/lib/help-search.js
index 6228f5ca97..567097a2eb 100644
--- a/deps/npm/test/lib/help-search.js
+++ b/deps/npm/test/lib/help-search.js
@@ -1,6 +1,7 @@
const { test } = require('tap')
const { join } = require('path')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const ansicolors = require('ansicolors')
const OUTPUT = []
@@ -8,26 +9,24 @@ const output = (msg) => {
OUTPUT.push(msg)
}
-let npmHelpArgs = null
-let npmHelpErr = null
-const npm = {
+const config = {
+ long: false,
+}
+const npmHelpErr = null
+const npm = mockNpm({
color: false,
+ config,
flatOptions: {
long: false,
},
+ usage: 'npm test usage',
commands: {
help: (args, cb) => {
- npmHelpArgs = args
return cb(npmHelpErr)
},
},
output,
-}
-
-let npmUsageArg = null
-const npmUsage = (npm, arg) => {
- npmUsageArg = arg
-}
+})
let globRoot = null
const globDir = {
@@ -45,7 +44,6 @@ const glob = (p, cb) =>
cb(null, Object.keys(globDir).map((file) => join(globRoot, file)))
const HelpSearch = requireInject('../../lib/help-search.js', {
- '../../lib/utils/npm-usage.js': npmUsage,
glob,
})
const helpSearch = new HelpSearch(npm)
@@ -61,8 +59,7 @@ test('npm help-search', t => {
if (err)
throw err
- t.match(OUTPUT, /Top hits for/, 'outputs results')
- t.match(OUTPUT, /Did you mean this\?\n\s+exec/, 'matched command, so suggest it')
+ t.match(OUTPUT, /Top hits for "exec"/, 'outputs results')
t.end()
})
})
@@ -84,46 +81,12 @@ test('npm help-search multiple terms', t => {
})
})
-test('npm help-search single result prints full section', t => {
- globRoot = t.testdir(globDir)
- t.teardown(() => {
- OUTPUT.length = 0
- npmHelpArgs = null
- globRoot = null
- })
-
- return helpSearch.exec(['does not exist in'], (err) => {
- if (err)
- throw err
-
- t.strictSame(npmHelpArgs, ['npm-install'], 'identified the correct man page and called help with it')
- t.end()
- })
-})
-
-test('npm help-search single result propagates error', t => {
- globRoot = t.testdir(globDir)
- npmHelpErr = new Error('help broke')
- t.teardown(() => {
- OUTPUT.length = 0
- npmHelpArgs = null
- npmHelpErr = null
- globRoot = null
- })
-
- 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()
- })
-})
-
test('npm help-search long output', t => {
globRoot = t.testdir(globDir)
- npm.flatOptions.long = true
+ config.long = true
t.teardown(() => {
OUTPUT.length = 0
- npm.flatOptions.long = false
+ config.long = false
globRoot = null
})
@@ -138,11 +101,11 @@ test('npm help-search long output', t => {
test('npm help-search long output with color', t => {
globRoot = t.testdir(globDir)
- npm.flatOptions.long = true
+ config.long = true
npm.color = true
t.teardown(() => {
OUTPUT.length = 0
- npm.flatOptions.long = false
+ config.long = false
npm.color = false
globRoot = null
})
@@ -159,7 +122,8 @@ test('npm help-search long output with color', t => {
test('npm help-search no args', t => {
return helpSearch.exec([], (err) => {
- t.match(err, /npm help-search/, 'throws usage')
+ t.notOk(err)
+ t.match(OUTPUT, /npm help-search/, 'outputs usage')
t.end()
})
})
@@ -168,7 +132,6 @@ test('npm help-search no matches', t => {
globRoot = t.testdir(globDir)
t.teardown(() => {
OUTPUT.length = 0
- npmUsageArg = null
globRoot = null
})
@@ -176,7 +139,7 @@ test('npm help-search no matches', t => {
if (err)
throw err
- t.equal(npmUsageArg, false, 'called npmUsage for no matches')
+ t.match(OUTPUT, /No matches/)
t.end()
})
})
diff --git a/deps/npm/test/lib/help.js b/deps/npm/test/lib/help.js
index ae2f7e99da..ccf13a7e46 100644
--- a/deps/npm/test/lib/help.js
+++ b/deps/npm/test/lib/help.js
@@ -2,11 +2,6 @@ const { test } = require('tap')
const requireInject = require('require-inject')
const { EventEmitter } = require('events')
-let npmUsageArg = null
-const npmUsage = (npm, arg) => {
- npmUsageArg = arg
-}
-
const npmConfig = {
usage: false,
viewer: undefined,
@@ -16,6 +11,7 @@ const npmConfig = {
let helpSearchArgs = null
const OUTPUT = []
const npm = {
+ usage: 'test npm usage',
config: {
get: (key) => npmConfig[key],
set: (key, value) => {
@@ -48,7 +44,9 @@ const globDefaults = [
let globErr = null
let globResult = globDefaults
+let globParam
const glob = (p, cb) => {
+ globParam = p
return cb(globErr, globResult)
}
@@ -71,7 +69,6 @@ const openUrl = async (npm, url, msg) => {
}
const Help = requireInject('../../lib/help.js', {
- '../../lib/utils/npm-usage.js': npmUsage,
'../../lib/utils/open-url.js': openUrl,
child_process: {
spawn,
@@ -81,15 +78,11 @@ const Help = requireInject('../../lib/help.js', {
const help = new Help(npm)
test('npm help', t => {
- t.teardown(() => {
- npmUsageArg = null
- })
-
return help.exec([], (err) => {
if (err)
throw err
- t.equal(npmUsageArg, false, 'called npmUsage')
+ t.match(OUTPUT, ['test npm usage'], 'showed npm usage')
t.end()
})
})
@@ -107,22 +100,6 @@ test('npm help completion', async t => {
t.rejects(help.completion({ conf: { argv: { remain: [] } } }), /glob failed/, 'glob errors propagate')
})
-test('npm help -h', t => {
- npmConfig.usage = true
- t.teardown(() => {
- npmConfig.usage = false
- OUTPUT.length = 0
- })
-
- return help.exec(['help'], (err) => {
- if (err)
- throw err
-
- t.strictSame(OUTPUT, ['npm help <term>'], 'outputs usage information for command')
- t.end()
- })
-})
-
test('npm help multiple args calls search', t => {
t.teardown(() => {
helpSearchArgs = null
@@ -180,7 +157,7 @@ test('npm help whoami', t => {
throw err
t.equal(spawnBin, 'man', 'calls man by default')
- t.strictSame(spawnArgs, ['1', 'npm-whoami'], 'passes the correct arguments')
+ t.strictSame(spawnArgs, [globResult[0]], 'passes the correct arguments')
t.end()
})
})
@@ -212,12 +189,12 @@ test('npm help 5 install', t => {
npmConfig.viewer = 'browser'
globResult = [
'/root/man/man5/install.5',
- '/root/man/man1/npm-install.1',
]
t.teardown(() => {
npmConfig.viewer = undefined
globResult = globDefaults
+ globParam = null
spawnBin = null
spawnArgs = null
})
@@ -226,6 +203,7 @@ test('npm help 5 install', t => {
if (err)
throw err
+ t.match(globParam, /man5/, 'searches only in man5 folder')
t.match(openUrlArg, /configuring-npm(\/|\\)install.html$/, 'attempts to open the correct url')
t.end()
})
@@ -234,11 +212,11 @@ test('npm help 5 install', t => {
test('npm help 7 config', t => {
npmConfig.viewer = 'browser'
globResult = [
- '/root/man/man1/npm-config.1',
'/root/man/man7/config.7',
]
t.teardown(() => {
npmConfig.viewer = undefined
+ globParam = null
globResult = globDefaults
spawnBin = null
spawnArgs = null
@@ -248,49 +226,12 @@ test('npm help 7 config', t => {
if (err)
throw err
+ t.match(globParam, /man7/, 'searches only in man5 folder')
t.match(openUrlArg, /using-npm(\/|\\)config.html$/, 'attempts to open the correct url')
t.end()
})
})
-test('npm help with browser viewer and invalid section throws', t => {
- npmConfig.viewer = 'browser'
- globResult = [
- '/root/man/man1/npm-config.1',
- '/root/man/man7/config.7',
- '/root/man/man9/config.9',
- ]
- t.teardown(() => {
- npmConfig.viewer = undefined
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
- })
-
- return help.exec(['9', 'config'], (err) => {
- t.match(err, /invalid man section: 9/, 'throws appropriate error')
- t.end()
- })
-})
-
-test('npm help global redirects to folders', t => {
- globResult = ['/root/man/man5/folders.5']
- t.teardown(() => {
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
- })
-
- return help.exec(['global'], (err) => {
- if (err)
- throw err
-
- t.equal(spawnBin, 'man', 'calls man by default')
- t.strictSame(spawnArgs, ['5', 'folders'], 'passes the correct arguments')
- t.end()
- })
-})
-
test('npm help package.json redirects to package-json', t => {
globResult = ['/root/man/man5/package-json.5']
t.teardown(() => {
@@ -304,7 +245,8 @@ test('npm help package.json redirects to package-json', t => {
throw err
t.equal(spawnBin, 'man', 'calls man by default')
- t.strictSame(spawnArgs, ['5', 'package-json'], 'passes the correct arguments')
+ t.match(globParam, /package-json/, 'glob was asked to find package-json')
+ t.strictSame(spawnArgs, [globResult[0]], 'passes the correct arguments')
t.end()
})
})
@@ -327,7 +269,7 @@ test('npm help ?(un)star', t => {
throw err
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')
+ t.strictSame(spawnArgs, ['-e', `(woman-find-file '/root/man/man1/npm-star.1')`], 'passes the correct arguments')
t.end()
})
})
@@ -350,7 +292,7 @@ test('npm help - woman viewer propagates errors', t => {
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')
+ t.strictSame(spawnArgs, ['-e', `(woman-find-file '/root/man/man1/npm-star.1')`], 'passes the correct arguments')
t.end()
})
})
@@ -372,7 +314,7 @@ test('npm help un*', t => {
throw err
t.equal(spawnBin, 'man', 'calls man by default')
- t.strictSame(spawnArgs, ['1', 'npm-unstar'], 'passes the correct arguments')
+ t.strictSame(spawnArgs, ['/root/man/man1/npm-uninstall.1'], 'passes the correct arguments')
t.end()
})
})
@@ -394,7 +336,7 @@ test('npm help - man viewer propagates errors', t => {
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')
+ t.strictSame(spawnArgs, ['/root/man/man1/npm-uninstall.1'], 'passes the correct arguments')
t.end()
})
})
diff --git a/deps/npm/test/lib/init.js b/deps/npm/test/lib/init.js
index 8b9f32e156..2b212f4a15 100644
--- a/deps/npm/test/lib/init.js
+++ b/deps/npm/test/lib/init.js
@@ -1,5 +1,6 @@
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
let result = ''
const npmLog = {
@@ -10,14 +11,17 @@ const npmLog = {
resume: () => null,
silly: () => null,
}
-const npm = {
- config: { set () {} },
- flatOptions: {},
+const config = {
+ 'init-module': '~/.npm-init.js',
+}
+const npm = mockNpm({
+ config,
log: npmLog,
+ commands: {},
output: (...msg) => {
result += msg.join('\n')
},
-}
+})
const mocks = {
'init-package-json': (dir, initFile, config, cb) => cb(null, 'data'),
'../../lib/utils/usage.js': () => 'usage instructions',
@@ -27,19 +31,13 @@ const init = new Init(npm)
t.afterEach(cb => {
result = ''
- npm.config = { get: () => '', set () {} }
+ config.package = undefined
npm.commands = {}
- Object.defineProperty(npm, 'flatOptions', { value: {} })
npm.log = npmLog
cb()
})
t.test('classic npm init no args', t => {
- npm.config = {
- get () {
- return '~/.npm-init.js'
- },
- }
init.exec([], err => {
t.ifError(err, 'npm init no args')
t.matchSnapshot(result, 'should print helper info')
@@ -49,9 +47,7 @@ t.test('classic npm init no args', t => {
t.test('classic npm init -y', t => {
t.plan(7)
- npm.config = {
- get: () => '~/.npm-init.js',
- }
+ config.yes = true
Object.defineProperty(npm, 'flatOptions', { value: { yes: true} })
npm.log = { ...npm.log }
npm.log.silly = (title, msg) => {
@@ -72,14 +68,9 @@ t.test('classic npm init -y', t => {
})
t.test('npm init <arg>', t => {
- t.plan(4)
- npm.config = {
- set (key, val) {
- t.equal(key, 'package', 'should set package key')
- t.deepEqual(val, [], 'should set empty array value')
- },
- }
+ t.plan(3)
npm.commands.exec = (arr, cb) => {
+ t.deepEqual(config.package, [], 'should set empty array value')
t.deepEqual(
arr,
['create-react-app'],
@@ -178,20 +169,9 @@ t.test('npm init exec error', t => {
})
t.test('should not rewrite flatOptions', t => {
- t.plan(4)
- Object.defineProperty(npm, 'flatOptions', {
- get: () => ({}),
- set () {
- throw new Error('Should not set flatOptions')
- },
- })
- npm.config = {
- set (key, val) {
- t.equal(key, 'package', 'should set package key')
- t.deepEqual(val, [], 'should set empty array value')
- },
- }
+ t.plan(3)
npm.commands.exec = (arr, cb) => {
+ t.deepEqual(config.package, [], 'should set empty array value')
t.deepEqual(
arr,
['create-react-app', 'my-app'],
diff --git a/deps/npm/test/lib/install.js b/deps/npm/test/lib/install.js
index 8b7a968511..b44452a69c 100644
--- a/deps/npm/test/lib/install.js
+++ b/deps/npm/test/lib/install.js
@@ -2,6 +2,7 @@ const { test } = require('tap')
const Install = require('../../lib/install.js')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
test('should install using Arborist', (t) => {
const SCRIPTS = []
@@ -28,16 +29,14 @@ test('should install using Arborist', (t) => {
throw new Error('got wrong object passed to reify-finish')
},
})
- const install = new Install({
+
+ const npm = mockNpm({
+ config: { dev: true },
+ flatOptions: { global: false },
globalDir: 'path/to/node_modules/',
prefix: 'foo',
- flatOptions: {
- global: false,
- },
- config: {
- get: () => true,
- },
})
+ const install = new Install(npm)
t.test('with args', t => {
install.exec(['fizzbuzz'], er => {
@@ -86,17 +85,16 @@ test('should ignore scripts with --ignore-scripts', (t) => {
}
},
})
- const install = new Install({
+ const npm = mockNpm({
globalDir: 'path/to/node_modules/',
prefix: 'foo',
- flatOptions: {
- global: false,
- ignoreScripts: true,
- },
+ flatOptions: { global: false },
config: {
- get: () => false,
+ global: false,
+ 'ignore-scripts': true,
},
})
+ const install = new Install(npm)
install.exec([], er => {
if (er)
throw er
@@ -113,16 +111,13 @@ test('should install globally using Arborist', (t) => {
this.reify = () => {}
},
})
- const install = new Install({
+ const npm = mockNpm({
globalDir: 'path/to/node_modules/',
prefix: 'foo',
- flatOptions: {
- global: true,
- },
- config: {
- get: () => false,
- },
+ config: { global: true },
+ flatOptions: { global: true },
})
+ const install = new Install(npm)
install.exec([], er => {
if (er)
throw er
diff --git a/deps/npm/test/lib/link.js b/deps/npm/test/lib/link.js
index be7af3f524..0d96ba0bcd 100644
--- a/deps/npm/test/lib/link.js
+++ b/deps/npm/test/lib/link.js
@@ -3,6 +3,7 @@ const { resolve } = require('path')
const Arborist = require('@npmcli/arborist')
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const redactCwd = (path) => {
const normalizePath = p => p
@@ -15,17 +16,13 @@ const redactCwd = (path) => {
t.cleanSnapshot = (str) => redactCwd(str)
let reifyOutput
-const npm = {
+const config = {}
+const npm = mockNpm({
globalDir: null,
prefix: null,
- flatOptions: {},
- config: {
- get () {
- return false
- },
- find () {},
- },
-}
+ config,
+})
+
const printLinks = async (opts) => {
let res = ''
const arb = new Arborist(opts)
diff --git a/deps/npm/test/lib/load-all-commands.js b/deps/npm/test/lib/load-all-commands.js
index e31a2b9936..d7eb2eae0a 100644
--- a/deps/npm/test/lib/load-all-commands.js
+++ b/deps/npm/test/lib/load-all-commands.js
@@ -1,27 +1,37 @@
-// Thanks to nyc not working properly with proxies this
-// doesn't affect coverage. but it does ensure that every command has a usage
-// that contains its name, and if it has completion it is a function
-const npm = require('../../lib/npm.js')
+// Thanks to nyc not working properly with proxies this doesn't affect
+// coverage. but it does ensure that every command has a usage that renders,
+// contains its name, a description, and if it has completion it is a function.
+// That it renders also ensures that any params we've defined in our commands
+// work.
+const requireInject = require('require-inject')
+const npm = requireInject('../../lib/npm.js')
const t = require('tap')
const { cmdList } = require('../../lib/utils/cmd-list.js')
-t.test('load npm', t => npm.load(er => {
- if (er)
- throw er
-}))
-
+let npmOutput = []
+npm.output = (msg) => {
+ npmOutput = msg
+}
t.test('load each command', t => {
- t.plan(cmdList.length)
- for (const cmd of cmdList.sort((a, b) => a.localeCompare(b))) {
- t.test(cmd, t => {
- const impl = npm.commands[cmd]
- if (impl.completion) {
- t.plan(3)
- t.isa(impl.completion, 'function', 'completion, if present, is a function')
- } else
- t.plan(2)
- t.isa(impl, 'function', 'implementation is a function')
- t.match(impl.usage, cmd, 'usage contains the command')
- })
- }
+ t.plan(cmdList.length + 1)
+ npm.load((er) => {
+ t.notOk(er)
+ npm.config.set('usage', true)
+ for (const cmd of cmdList.sort((a, b) => a.localeCompare(b))) {
+ t.test(cmd, t => {
+ const impl = npm.commands[cmd]
+ if (impl.completion)
+ t.isa(impl.completion, 'function', 'completion, if present, is a function')
+ t.isa(impl, 'function', 'implementation is a function')
+ t.ok(impl.description, 'implementation has a description')
+ t.ok(impl.name, 'implementation has a name')
+ t.match(impl.usage, cmd, 'usage contains the command')
+ impl([], (err) => {
+ t.notOk(err)
+ t.match(npmOutput, impl.usage, 'usage is output')
+ t.end()
+ })
+ })
+ }
+ })
})
diff --git a/deps/npm/test/lib/logout.js b/deps/npm/test/lib/logout.js
index b00fa641d8..bae797f969 100644
--- a/deps/npm/test/lib/logout.js
+++ b/deps/npm/test/lib/logout.js
@@ -1,12 +1,17 @@
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const { test } = require('tap')
-const _flatOptions = {
+const config = {
registry: 'https://registry.npmjs.org/',
scope: '',
}
+const flatOptions = {
+ registry: 'https://registry.npmjs.org/',
+ scope: '',
+}
+const npm = mockNpm({ config, flatOptions })
-const config = {}
const npmlog = {}
let result = null
@@ -20,15 +25,12 @@ const mocks = {
}
const Logout = requireInject('../../lib/logout.js', mocks)
-const logout = new Logout({
- flatOptions: _flatOptions,
- config,
-})
+const logout = new Logout(npm)
test('token logout', async (t) => {
t.plan(6)
- _flatOptions.token = '@foo/'
+ flatOptions.token = '@foo/'
npmlog.verbose = (title, msg) => {
t.equal(title, 'logout', 'should have correcct log prefix')
@@ -39,7 +41,7 @@ test('token logout', async (t) => {
)
}
- config.clearCredentialsByURI = (registry) => {
+ npm.config.clearCredentialsByURI = (registry) => {
t.equal(
registry,
'https://registry.npmjs.org/',
@@ -47,7 +49,7 @@ test('token logout', async (t) => {
)
}
- config.save = (type) => {
+ npm.config.save = (type) => {
t.equal(type, 'user', 'should save to user config')
}
@@ -70,7 +72,7 @@ test('token logout', async (t) => {
'should call npm-registry-fetch with expected values'
)
- delete _flatOptions.token
+ delete flatOptions.token
result = null
mocks['npm-registry-fetch'] = null
config.clearCredentialsByURI = null
@@ -86,9 +88,11 @@ test('token logout', async (t) => {
test('token scoped logout', async (t) => {
t.plan(8)
- _flatOptions.token = '@foo/'
- _flatOptions.scope = '@myscope'
- _flatOptions['@myscope:registry'] = 'https://diff-registry.npmjs.com/'
+ flatOptions.token = '@foo/'
+ config.scope = '@myscope'
+ config['@myscope:registry'] = 'https://diff-registry.npmjs.com/'
+ flatOptions.scope = '@myscope'
+ flatOptions['@myscope:registry'] = 'https://diff-registry.npmjs.com/'
npmlog.verbose = (title, msg) => {
t.equal(title, 'logout', 'should have correcct log prefix')
@@ -99,7 +103,7 @@ test('token scoped logout', async (t) => {
)
}
- config.clearCredentialsByURI = (registry) => {
+ npm.config.clearCredentialsByURI = (registry) => {
t.equal(
registry,
'https://diff-registry.npmjs.com/',
@@ -107,7 +111,7 @@ test('token scoped logout', async (t) => {
)
}
- config.delete = (ref, type) => {
+ npm.config.delete = (ref, type) => {
t.equal(
ref,
'@myscope:registry',
@@ -116,7 +120,7 @@ test('token scoped logout', async (t) => {
t.equal(type, 'user', 'should delete from user config')
}
- config.save = (type) => {
+ npm.config.save = (type) => {
t.equal(type, 'user', 'should save to user config')
}
@@ -140,9 +144,9 @@ test('token scoped logout', async (t) => {
'should call npm-registry-fetch with expected values'
)
- _flatOptions.scope = ''
- delete _flatOptions['@myscope:registry']
- delete _flatOptions.token
+ config.scope = ''
+ delete config['@myscope:registry']
+ delete flatOptions.token
result = null
mocks['npm-registry-fetch'] = null
config.clearCredentialsByURI = null
@@ -158,8 +162,8 @@ test('token scoped logout', async (t) => {
test('user/pass logout', async (t) => {
t.plan(3)
- _flatOptions.username = 'foo'
- _flatOptions.password = 'bar'
+ flatOptions.username = 'foo'
+ flatOptions.password = 'bar'
npmlog.verbose = (title, msg) => {
t.equal(title, 'logout', 'should have correcct log prefix')
@@ -170,17 +174,17 @@ test('user/pass logout', async (t) => {
)
}
- config.clearCredentialsByURI = () => null
- config.save = () => null
+ npm.config.clearCredentialsByURI = () => null
+ npm.config.save = () => null
await new Promise((res, rej) => {
logout.exec([], (err) => {
t.ifError(err, 'should not error out')
- delete _flatOptions.username
- delete _flatOptions.password
- config.clearCredentialsByURI = null
- config.save = null
+ delete flatOptions.username
+ delete flatOptions.password
+ npm.config.clearCredentialsByURI = null
+ npm.config.save = null
npmlog.verbose = null
res()
@@ -203,9 +207,9 @@ test('missing credentials', (t) => {
test('ignore invalid scoped registry config', async (t) => {
t.plan(5)
- _flatOptions.token = '@foo/'
- _flatOptions.scope = '@myscope'
- _flatOptions['@myscope:registry'] = ''
+ flatOptions.token = '@foo/'
+ config.scope = '@myscope'
+ flatOptions['@myscope:registry'] = ''
npmlog.verbose = (title, msg) => {
t.equal(title, 'logout', 'should have correcct log prefix')
@@ -216,7 +220,7 @@ test('ignore invalid scoped registry config', async (t) => {
)
}
- config.clearCredentialsByURI = (registry) => {
+ npm.config.clearCredentialsByURI = (registry) => {
t.equal(
registry,
'https://registry.npmjs.org/',
@@ -224,8 +228,8 @@ test('ignore invalid scoped registry config', async (t) => {
)
}
- config.delete = () => null
- config.save = () => null
+ npm.config.delete = () => null
+ npm.config.save = () => null
await new Promise((res, rej) => {
logout.exec([], (err) => {
@@ -247,7 +251,7 @@ test('ignore invalid scoped registry config', async (t) => {
'should call npm-registry-fetch with expected values'
)
- delete _flatOptions.token
+ delete flatOptions.token
result = null
mocks['npm-registry-fetch'] = null
config.clearCredentialsByURI = null
diff --git a/deps/npm/test/lib/ls.js b/deps/npm/test/lib/ls.js
index bcbd341356..5367dec688 100644
--- a/deps/npm/test/lib/ls.js
+++ b/deps/npm/test/lib/ls.js
@@ -1,4 +1,5 @@
const t = require('tap')
+const mockNpm = require('../fixtures/mock-npm')
const { resolve } = require('path')
const { utimesSync } = require('fs')
@@ -84,12 +85,9 @@ const diffDepTypesNmFixture = {
},
}
-let prefix
-let globalDir = 'MISSING_GLOBAL_DIR'
let result = ''
-// note this _flatOptions representations is for tests-only and does not
-// represent exactly the properties found in the actual flatOptions obj
-const _flatOptions = {
+const LS = require('../../lib/ls.js')
+const config = {
all: true,
color: false,
dev: false,
@@ -99,32 +97,18 @@ const _flatOptions = {
link: false,
only: null,
parseable: false,
- get prefix () {
- return prefix
- },
production: false,
}
-const LS = require('../../lib/ls.js')
-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 flatOptions = {
+}
+const npm = mockNpm({
+ config,
+ flatOptions,
output: msg => {
result = msg
},
})
+const ls = new LS(npm)
const redactCwd = res =>
res && res.replace(/\\+/g, '/').replace(new RegExp(__dirname.replace(/\\+/g, '/'), 'gi'), '{CWD}')
@@ -138,10 +122,10 @@ const cleanUpResult = (done, t) => {
t.test('ls', (t) => {
t.beforeEach(cleanUpResult)
- _flatOptions.json = false
- _flatOptions.unicode = false
+ config.json = false
+ config.unicode = false
t.test('no args', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -160,7 +144,7 @@ t.test('ls', (t) => {
})
t.test('missing package.json', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
...simpleNmFixture,
})
ls.exec([], (err) => {
@@ -175,7 +159,7 @@ t.test('ls', (t) => {
})
t.test('extraneous deps', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -198,8 +182,8 @@ t.test('ls', (t) => {
})
t.test('with filter arg', (t) => {
- _flatOptions.color = true
- prefix = t.testdir({
+ npm.color = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -213,15 +197,15 @@ t.test('ls', (t) => {
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
+ npm.color = false
t.end()
})
})
t.test('with dot filter arg', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = 0
- prefix = t.testdir({
+ config.all = false
+ config.depth = 0
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -235,14 +219,14 @@ t.test('ls', (t) => {
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
- _flatOptions.depth = Infinity
+ config.all = true
+ config.depth = Infinity
t.end()
})
})
t.test('with filter arg nested dep', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -261,7 +245,7 @@ t.test('ls', (t) => {
})
t.test('with multiple filter args', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -289,7 +273,7 @@ t.test('ls', (t) => {
})
t.test('with missing filter arg', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -314,9 +298,9 @@ t.test('ls', (t) => {
})
t.test('default --depth value should be 0', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = undefined
- prefix = t.testdir({
+ config.all = false
+ config.depth = undefined
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -330,16 +314,16 @@ t.test('ls', (t) => {
ls.exec([], (err) => {
t.ifError(err, 'npm ls')
t.matchSnapshot(redactCwd(result), 'should output tree containing only top-level dependencies')
- _flatOptions.all = true
- _flatOptions.depth = Infinity
+ config.all = true
+ config.depth = Infinity
t.end()
})
})
t.test('--depth=0', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = 0
- prefix = t.testdir({
+ config.all = false
+ config.depth = 0
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -353,16 +337,16 @@ t.test('ls', (t) => {
ls.exec([], (err) => {
t.ifError(err, 'npm ls')
t.matchSnapshot(redactCwd(result), 'should output tree containing only top-level dependencies')
- _flatOptions.all = true
- _flatOptions.depth = Infinity
+ config.all = true
+ config.depth = Infinity
t.end()
})
})
t.test('--depth=1', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = 1
- prefix = t.testdir({
+ config.all = false
+ config.depth = 1
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -414,14 +398,14 @@ t.test('ls', (t) => {
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
- _flatOptions.depth = Infinity
+ config.all = true
+ config.depth = Infinity
t.end()
})
})
t.test('missing/invalid/extraneous', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -447,8 +431,8 @@ t.test('ls', (t) => {
})
t.test('colored output', (t) => {
- _flatOptions.color = true
- prefix = t.testdir({
+ npm.color = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -462,14 +446,14 @@ t.test('ls', (t) => {
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
+ npm.color = false
t.end()
})
})
t.test('--dev', (t) => {
- _flatOptions.dev = true
- prefix = t.testdir({
+ config.dev = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -491,14 +475,14 @@ t.test('ls', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing dev deps')
- _flatOptions.dev = false
+ config.dev = false
t.end()
})
})
t.test('--only=development', (t) => {
- _flatOptions.only = 'development'
- prefix = t.testdir({
+ config.only = 'development'
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -520,14 +504,14 @@ t.test('ls', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing only development deps')
- _flatOptions.only = null
+ config.only = null
t.end()
})
})
t.test('--link', (t) => {
- _flatOptions.link = true
- prefix = t.testdir({
+ config.link = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -559,13 +543,13 @@ t.test('ls', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing linked deps')
- _flatOptions.link = false
+ config.link = false
t.end()
})
})
t.test('print deduped symlinks', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'print-deduped-symlinks',
version: '1.0.0',
@@ -595,14 +579,14 @@ t.test('ls', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing linked deps')
- _flatOptions.link = false
+ config.link = false
t.end()
})
})
t.test('--production', (t) => {
- _flatOptions.production = true
- prefix = t.testdir({
+ config.production = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -624,14 +608,14 @@ t.test('ls', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing production deps')
- _flatOptions.production = false
+ config.production = false
t.end()
})
})
t.test('--only=prod', (t) => {
- _flatOptions.only = 'prod'
- prefix = t.testdir({
+ config.only = 'prod'
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -653,14 +637,14 @@ t.test('ls', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing only prod deps')
- _flatOptions.only = null
+ config.only = null
t.end()
})
})
t.test('--long', (t) => {
- _flatOptions.long = true
- prefix = t.testdir({
+ config.long = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -682,16 +666,16 @@ t.test('ls', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree info with descriptions')
- _flatOptions.long = true
+ config.long = true
t.end()
})
})
t.test('--long --depth=0', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = 0
- _flatOptions.long = true
- prefix = t.testdir({
+ config.all = false
+ config.depth = 0
+ config.long = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -713,15 +697,15 @@ t.test('ls', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing top-level deps with descriptions')
- _flatOptions.all = true
- _flatOptions.depth = Infinity
- _flatOptions.long = false
+ config.all = true
+ config.depth = Infinity
+ config.long = false
t.end()
})
})
t.test('json read problems', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': '{broken json',
})
ls.exec([], (err) => {
@@ -732,7 +716,7 @@ t.test('ls', (t) => {
})
t.test('empty location', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
ls.exec([], (err) => {
t.ifError(err, 'should not error out on empty locations')
t.matchSnapshot(redactCwd(result), 'should print empty result')
@@ -741,7 +725,7 @@ t.test('ls', (t) => {
})
t.test('invalid peer dep', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -768,8 +752,8 @@ t.test('ls', (t) => {
})
t.test('invalid deduped dep', (t) => {
- _flatOptions.color = true
- prefix = t.testdir({
+ npm.color = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'invalid-deduped-dep',
version: '1.0.0',
@@ -798,13 +782,13 @@ t.test('ls', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree signaling mismatching peer dep in problems')
- _flatOptions.color = false
+ npm.color = false
t.end()
})
})
t.test('deduped missing dep', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -834,7 +818,7 @@ t.test('ls', (t) => {
})
t.test('unmet peer dep', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -852,8 +836,8 @@ t.test('ls', (t) => {
})
t.test('unmet optional dep', (t) => {
- _flatOptions.color = true
- prefix = t.testdir({
+ npm.color = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -878,13 +862,13 @@ t.test('ls', (t) => {
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')
- _flatOptions.color = false
+ npm.color = false
t.end()
})
})
t.test('cycle deps', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -921,8 +905,8 @@ t.test('ls', (t) => {
})
t.test('cycle deps with filter args', (t) => {
- _flatOptions.color = true
- prefix = t.testdir({
+ npm.color = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -954,13 +938,13 @@ t.test('ls', (t) => {
ls.exec(['a'], (err) => {
t.ifError(err, 'npm ls')
t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref')
- _flatOptions.color = false
+ npm.color = false
t.end()
})
})
t.test('with no args dedupe entries', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'dedupe-entries',
version: '1.0.0',
@@ -1007,9 +991,9 @@ t.test('ls', (t) => {
})
t.test('with no args dedupe entries and not displaying all', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = 0
- prefix = t.testdir({
+ config.all = false
+ config.depth = 0
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'dedupe-entries',
version: '1.0.0',
@@ -1051,15 +1035,15 @@ t.test('ls', (t) => {
ls.exec([], (err) => {
t.ifError(err, 'npm ls')
t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref')
- _flatOptions.all = true
- _flatOptions.depth = Infinity
+ config.all = true
+ config.depth = Infinity
t.end()
})
})
t.test('with args and dedupe entries', (t) => {
- _flatOptions.color = true
- prefix = t.testdir({
+ npm.color = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'dedupe-entries',
version: '1.0.0',
@@ -1101,13 +1085,13 @@ t.test('ls', (t) => {
ls.exec(['@npmcli/b'], (err) => {
t.ifError(err, 'npm ls')
t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref')
- _flatOptions.color = false
+ npm.color = false
t.end()
})
})
t.test('with args and different order of items', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'dedupe-entries',
version: '1.0.0',
@@ -1154,7 +1138,7 @@ t.test('ls', (t) => {
})
t.test('using aliases', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1189,7 +1173,7 @@ t.test('ls', (t) => {
},
},
})
- touchHiddenPackageLock(prefix)
+ touchHiddenPackageLock(npm.prefix)
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing aliases')
t.end()
@@ -1197,7 +1181,7 @@ t.test('ls', (t) => {
})
t.test('resolved points to git ref', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1235,7 +1219,7 @@ t.test('ls', (t) => {
},
},
})
- touchHiddenPackageLock(prefix)
+ touchHiddenPackageLock(npm.prefix)
ls.exec([], (err) => {
t.ifError(err, 'npm ls')
t.matchSnapshot(redactCwd(result), 'should output tree containing git refs')
@@ -1244,7 +1228,7 @@ t.test('ls', (t) => {
})
t.test('broken resolved field', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
node_modules: {
a: {
'package.json': JSON.stringify({
@@ -1288,7 +1272,7 @@ t.test('ls', (t) => {
})
t.test('from and resolved properties', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1334,7 +1318,7 @@ t.test('ls', (t) => {
},
},
})
- touchHiddenPackageLock(prefix)
+ touchHiddenPackageLock(npm.prefix)
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should not be printed in tree output')
t.end()
@@ -1342,7 +1326,7 @@ t.test('ls', (t) => {
})
t.test('global', (t) => {
- _flatOptions.global = true
+ config.global = true
const fixtures = t.testdir({
node_modules: {
a: {
@@ -1369,18 +1353,18 @@ t.test('ls', (t) => {
})
// mimics lib/npm.js globalDir getter but pointing to fixtures
- globalDir = resolve(fixtures, 'node_modules')
+ npm.globalDir = resolve(fixtures, 'node_modules')
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should print tree and not mark top-level items extraneous')
- globalDir = 'MISSING_GLOBAL_DIR'
- _flatOptions.global = false
+ npm.globalDir = 'MISSING_GLOBAL_DIR'
+ config.global = false
t.end()
})
})
t.test('filtering by child of missing dep', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'filter-by-child-of-missing-dep',
version: '1.0.0',
@@ -1432,7 +1416,7 @@ t.test('ls', (t) => {
})
t.test('loading a tree containing workspaces', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'filter-by-child-of-missing-dep',
version: '1.0.0',
@@ -1483,8 +1467,8 @@ t.test('ls', (t) => {
})
t.test('filter pkg arg using depth option', (t) => {
- _flatOptions.depth = 0
- prefix = t.testdir({
+ config.depth = 0
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-pkg-arg-filter-with-depth-opt',
version: '1.0.0',
@@ -1540,7 +1524,7 @@ t.test('ls', (t) => {
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
+ config.depth = null // default config value
ls.exec(['d'], (err) => {
t.ifError(err, 'should NOT have ELSPROBLEMS error code when filter')
t.matchSnapshot(redactCwd(result), 'should print expected result')
@@ -1550,7 +1534,7 @@ t.test('ls', (t) => {
})
t.teardown(() => {
- _flatOptions.depth = Infinity
+ config.depth = Infinity
})
t.end()
@@ -1558,11 +1542,11 @@ t.test('ls', (t) => {
t.test('ls --parseable', (t) => {
t.beforeEach(cleanUpResult)
- _flatOptions.json = false
- _flatOptions.unicode = false
- _flatOptions.parseable = true
+ config.json = false
+ config.unicode = false
+ config.parseable = true
t.test('no args', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1581,7 +1565,7 @@ t.test('ls --parseable', (t) => {
})
t.test('missing package.json', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
...simpleNmFixture,
})
ls.exec([], (err) => {
@@ -1596,7 +1580,7 @@ t.test('ls --parseable', (t) => {
})
t.test('extraneous deps', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1614,7 +1598,7 @@ t.test('ls --parseable', (t) => {
})
t.test('with filter arg', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1633,7 +1617,7 @@ t.test('ls --parseable', (t) => {
})
t.test('with filter arg nested dep', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1652,7 +1636,7 @@ t.test('ls --parseable', (t) => {
})
t.test('with multiple filter args', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1680,7 +1664,7 @@ t.test('ls --parseable', (t) => {
})
t.test('with missing filter arg', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1705,9 +1689,9 @@ t.test('ls --parseable', (t) => {
})
t.test('default --depth value should be 0', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = undefined
- prefix = t.testdir({
+ config.all = false
+ config.depth = undefined
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1721,16 +1705,16 @@ t.test('ls --parseable', (t) => {
ls.exec([], (err) => {
t.ifError(err, 'npm ls')
t.matchSnapshot(redactCwd(result), 'should output parseable output containing only top-level dependencies')
- _flatOptions.all = true
- _flatOptions.depth = Infinity
+ config.all = true
+ config.depth = Infinity
t.end()
})
})
t.test('--depth=0', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = 0
- prefix = t.testdir({
+ config.all = false
+ config.depth = 0
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1744,16 +1728,16 @@ t.test('ls --parseable', (t) => {
ls.exec([], (err) => {
t.ifError(err, 'npm ls')
t.matchSnapshot(redactCwd(result), 'should output tree containing only top-level dependencies')
- _flatOptions.all = true
- _flatOptions.depth = Infinity
+ config.all = true
+ config.depth = Infinity
t.end()
})
})
t.test('--depth=1', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = 1
- prefix = t.testdir({
+ config.all = false
+ config.depth = 1
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1767,14 +1751,14 @@ t.test('ls --parseable', (t) => {
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
- _flatOptions.depth = Infinity
+ config.all = true
+ config.depth = Infinity
t.end()
})
})
t.test('missing/invalid/extraneous', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1793,8 +1777,8 @@ t.test('ls --parseable', (t) => {
})
t.test('--dev', (t) => {
- _flatOptions.dev = true
- prefix = t.testdir({
+ config.dev = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1816,14 +1800,14 @@ t.test('ls --parseable', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing dev deps')
- _flatOptions.dev = false
+ config.dev = false
t.end()
})
})
t.test('--only=development', (t) => {
- _flatOptions.only = 'development'
- prefix = t.testdir({
+ config.only = 'development'
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1845,14 +1829,14 @@ t.test('ls --parseable', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing only development deps')
- _flatOptions.only = null
+ config.only = null
t.end()
})
})
t.test('--link', (t) => {
- _flatOptions.link = true
- prefix = t.testdir({
+ config.link = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1884,14 +1868,14 @@ t.test('ls --parseable', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing linked deps')
- _flatOptions.link = false
+ config.link = false
t.end()
})
})
t.test('--production', (t) => {
- _flatOptions.production = true
- prefix = t.testdir({
+ config.production = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1913,14 +1897,14 @@ t.test('ls --parseable', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing production deps')
- _flatOptions.production = false
+ config.production = false
t.end()
})
})
t.test('--only=prod', (t) => {
- _flatOptions.only = 'prod'
- prefix = t.testdir({
+ config.only = 'prod'
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1942,14 +1926,14 @@ t.test('ls --parseable', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing only prod deps')
- _flatOptions.only = null
+ config.only = null
t.end()
})
})
t.test('--long', (t) => {
- _flatOptions.long = true
- prefix = t.testdir({
+ config.long = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1971,13 +1955,13 @@ t.test('ls --parseable', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree info with descriptions')
- _flatOptions.long = true
+ config.long = true
t.end()
})
})
t.test('--long with extraneous deps', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -1996,8 +1980,8 @@ t.test('ls --parseable', (t) => {
})
t.test('--long missing/invalid/extraneous', (t) => {
- _flatOptions.long = true
- prefix = t.testdir({
+ config.long = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2011,14 +1995,14 @@ t.test('ls --parseable', (t) => {
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
+ config.long = false
t.end()
})
})
t.test('--long print symlink target location', (t) => {
- _flatOptions.long = true
- prefix = t.testdir({
+ config.long = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2051,16 +2035,16 @@ t.test('ls --parseable', (t) => {
ls.exec([], (err) => {
t.ifError(err, 'npm ls')
t.matchSnapshot(redactCwd(result), 'should output parseable results with symlink targets')
- _flatOptions.long = false
+ config.long = false
t.end()
})
})
t.test('--long --depth=0', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = 0
- _flatOptions.long = true
- prefix = t.testdir({
+ config.all = false
+ config.depth = 0
+ config.long = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2082,15 +2066,15 @@ t.test('ls --parseable', (t) => {
})
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing top-level deps with descriptions')
- _flatOptions.all = true
- _flatOptions.depth = Infinity
- _flatOptions.long = false
+ config.all = true
+ config.depth = Infinity
+ config.long = false
t.end()
})
})
t.test('json read problems', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': '{broken json',
})
ls.exec([], (err) => {
@@ -2101,7 +2085,7 @@ t.test('ls --parseable', (t) => {
})
t.test('empty location', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
ls.exec([], (err) => {
t.ifError(err, 'should not error out on empty locations')
t.matchSnapshot(redactCwd(result), 'should print empty result')
@@ -2110,7 +2094,7 @@ t.test('ls --parseable', (t) => {
})
t.test('unmet peer dep', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2137,7 +2121,7 @@ t.test('ls --parseable', (t) => {
})
t.test('unmet optional dep', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2167,7 +2151,7 @@ t.test('ls --parseable', (t) => {
})
t.test('cycle deps', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2203,7 +2187,7 @@ t.test('ls --parseable', (t) => {
})
t.test('using aliases', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2234,7 +2218,7 @@ t.test('ls --parseable', (t) => {
},
},
})
- touchHiddenPackageLock(prefix)
+ touchHiddenPackageLock(npm.prefix)
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing aliases')
t.end()
@@ -2242,7 +2226,7 @@ t.test('ls --parseable', (t) => {
})
t.test('resolved points to git ref', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2279,7 +2263,7 @@ t.test('ls --parseable', (t) => {
},
},
})
- touchHiddenPackageLock(prefix)
+ touchHiddenPackageLock(npm.prefix)
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should output tree containing git refs')
t.end()
@@ -2287,7 +2271,7 @@ t.test('ls --parseable', (t) => {
})
t.test('from and resolved properties', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2333,7 +2317,7 @@ t.test('ls --parseable', (t) => {
},
},
})
- touchHiddenPackageLock(prefix)
+ touchHiddenPackageLock(npm.prefix)
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should not be printed in tree output')
t.end()
@@ -2341,7 +2325,7 @@ t.test('ls --parseable', (t) => {
})
t.test('global', (t) => {
- _flatOptions.global = true
+ config.global = true
const fixtures = t.testdir({
node_modules: {
a: {
@@ -2368,12 +2352,12 @@ t.test('ls --parseable', (t) => {
})
// mimics lib/npm.js globalDir getter but pointing to fixtures
- globalDir = resolve(fixtures, 'node_modules')
+ npm.globalDir = resolve(fixtures, 'node_modules')
ls.exec([], () => {
t.matchSnapshot(redactCwd(result), 'should print parseable output for global deps')
- globalDir = 'MISSING_GLOBAL_DIR'
- _flatOptions.global = false
+ npm.globalDir = 'MISSING_GLOBAL_DIR'
+ config.global = false
t.end()
})
})
@@ -2383,10 +2367,10 @@ t.test('ls --parseable', (t) => {
t.test('ls --json', (t) => {
t.beforeEach(cleanUpResult)
- _flatOptions.json = true
- _flatOptions.parseable = false
+ config.json = true
+ config.parseable = false
t.test('no args', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2425,7 +2409,7 @@ t.test('ls --json', (t) => {
})
t.test('missing package.json', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
...simpleNmFixture,
})
ls.exec([], (err) => {
@@ -2474,7 +2458,7 @@ t.test('ls --json', (t) => {
})
t.test('extraneous deps', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2528,7 +2512,7 @@ t.test('ls --json', (t) => {
})
t.test('with filter arg', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2564,7 +2548,7 @@ t.test('ls --json', (t) => {
})
t.test('with filter arg nested dep', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2600,7 +2584,7 @@ t.test('ls --json', (t) => {
})
t.test('with multiple filter args', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2648,7 +2632,7 @@ t.test('ls --json', (t) => {
})
t.test('with missing filter arg', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2680,9 +2664,9 @@ t.test('ls --json', (t) => {
})
t.test('default --depth value should now be 0', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = undefined
- prefix = t.testdir({
+ config.all = false
+ config.depth = undefined
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2711,16 +2695,16 @@ t.test('ls --json', (t) => {
},
'should output json containing only top-level dependencies'
)
- _flatOptions.all = true
- _flatOptions.depth = Infinity
+ config.all = true
+ config.depth = Infinity
t.end()
})
})
t.test('--depth=0', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = 0
- prefix = t.testdir({
+ config.all = false
+ config.depth = 0
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2749,16 +2733,16 @@ t.test('ls --json', (t) => {
},
'should output json containing only top-level dependencies'
)
- _flatOptions.all = true
- _flatOptions.depth = Infinity
+ config.all = true
+ config.depth = Infinity
t.end()
})
})
t.test('--depth=1', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = 1
- prefix = t.testdir({
+ config.all = false
+ config.depth = 1
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2792,14 +2776,14 @@ t.test('ls --json', (t) => {
},
'should output json containing top-level deps and their deps only'
)
- _flatOptions.all = true
- _flatOptions.depth = Infinity
+ config.all = true
+ config.depth = Infinity
t.end()
})
})
t.test('missing/invalid/extraneous', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2858,8 +2842,8 @@ t.test('ls --json', (t) => {
})
t.test('--dev', (t) => {
- _flatOptions.dev = true
- prefix = t.testdir({
+ config.dev = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2899,14 +2883,14 @@ t.test('ls --json', (t) => {
},
'should output json containing dev deps'
)
- _flatOptions.dev = false
+ config.dev = false
t.end()
})
})
t.test('--only=development', (t) => {
- _flatOptions.only = 'development'
- prefix = t.testdir({
+ config.only = 'development'
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2946,14 +2930,14 @@ t.test('ls --json', (t) => {
},
'should output json containing only development deps'
)
- _flatOptions.only = null
+ config.only = null
t.end()
})
})
t.test('--link', (t) => {
- _flatOptions.link = true
- prefix = t.testdir({
+ config.link = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -2998,14 +2982,14 @@ t.test('ls --json', (t) => {
},
'should output json containing linked deps'
)
- _flatOptions.link = false
+ config.link = false
t.end()
})
})
t.test('--production', (t) => {
- _flatOptions.production = true
- prefix = t.testdir({
+ config.production = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -3039,14 +3023,14 @@ t.test('ls --json', (t) => {
},
'should output json containing production deps'
)
- _flatOptions.production = false
+ config.production = false
t.end()
})
})
t.test('--only=prod', (t) => {
- _flatOptions.only = 'prod'
- prefix = t.testdir({
+ config.only = 'prod'
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -3080,13 +3064,13 @@ t.test('ls --json', (t) => {
},
'should output json containing only prod deps'
)
- _flatOptions.only = null
+ config.only = null
t.end()
})
})
t.test('from lockfile', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
node_modules: {
'@isaacs': {
'dedupe-tests-a': {
@@ -3215,8 +3199,8 @@ t.test('ls --json', (t) => {
})
t.test('--long', (t) => {
- _flatOptions.long = true
- prefix = t.testdir({
+ config.long = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -3345,16 +3329,16 @@ t.test('ls --json', (t) => {
},
'should output long json info'
)
- _flatOptions.long = true
+ config.long = true
t.end()
})
})
t.test('--long --depth=0', (t) => {
- _flatOptions.all = false
- _flatOptions.depth = 0
- _flatOptions.long = true
- prefix = t.testdir({
+ config.all = false
+ config.depth = 0
+ config.long = true
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -3446,15 +3430,15 @@ t.test('ls --json', (t) => {
},
'should output json containing top-level deps in long format'
)
- _flatOptions.all = true
- _flatOptions.depth = Infinity
- _flatOptions.long = false
+ config.all = true
+ config.depth = Infinity
+ config.long = false
t.end()
})
})
t.test('json read problems', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': '{broken json',
})
ls.exec([], (err) => {
@@ -3475,7 +3459,7 @@ t.test('ls --json', (t) => {
})
t.test('empty location', (t) => {
- prefix = t.testdir({})
+ npm.prefix = t.testdir({})
ls.exec([], (err) => {
t.ifError(err, 'should not error out on empty locations')
t.deepEqual(
@@ -3488,7 +3472,7 @@ t.test('ls --json', (t) => {
})
t.test('unmet peer dep', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -3547,7 +3531,7 @@ t.test('ls --json', (t) => {
})
t.test('unmet optional dep', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -3611,7 +3595,7 @@ t.test('ls --json', (t) => {
})
t.test('cycle deps', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -3667,7 +3651,7 @@ t.test('ls --json', (t) => {
})
t.test('using aliases', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -3697,7 +3681,7 @@ t.test('ls --json', (t) => {
},
},
})
- touchHiddenPackageLock(prefix)
+ touchHiddenPackageLock(npm.prefix)
ls.exec([], () => {
t.deepEqual(
jsonParse(result),
@@ -3718,7 +3702,7 @@ t.test('ls --json', (t) => {
})
t.test('resolved points to git ref', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -3757,7 +3741,7 @@ t.test('ls --json', (t) => {
},
},
})
- touchHiddenPackageLock(prefix)
+ touchHiddenPackageLock(npm.prefix)
ls.exec([], () => {
t.deepEqual(
jsonParse(result),
@@ -3778,7 +3762,7 @@ t.test('ls --json', (t) => {
})
t.test('from and resolved properties', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'test-npm-ls',
version: '1.0.0',
@@ -3841,7 +3825,7 @@ t.test('ls --json', (t) => {
},
},
})
- touchHiddenPackageLock(prefix)
+ touchHiddenPackageLock(npm.prefix)
ls.exec([], () => {
t.deepEqual(
jsonParse(result),
@@ -3862,7 +3846,7 @@ t.test('ls --json', (t) => {
})
t.test('node.name fallback if missing root package name', (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
version: '1.0.0',
}),
@@ -3881,7 +3865,7 @@ t.test('ls --json', (t) => {
})
t.test('global', (t) => {
- _flatOptions.global = true
+ config.global = true
const fixtures = t.testdir({
node_modules: {
a: {
@@ -3908,7 +3892,7 @@ t.test('ls --json', (t) => {
})
// mimics lib/npm.js globalDir getter but pointing to fixtures
- globalDir = resolve(fixtures, 'node_modules')
+ npm.globalDir = resolve(fixtures, 'node_modules')
ls.exec([], () => {
t.deepEqual(
@@ -3931,8 +3915,8 @@ t.test('ls --json', (t) => {
},
'should print json output for global deps'
)
- globalDir = 'MISSING_GLOBAL_DIR'
- _flatOptions.global = false
+ npm.globalDir = 'MISSING_GLOBAL_DIR'
+ config.global = false
t.end()
})
})
diff --git a/deps/npm/test/lib/npm.js b/deps/npm/test/lib/npm.js
index 87cbea8f2c..5739193980 100644
--- a/deps/npm/test/lib/npm.js
+++ b/deps/npm/test/lib/npm.js
@@ -42,7 +42,7 @@ const npmlog = require('npmlog')
const npmPath = resolve(__dirname, '..', '..')
const Config = require('@npmcli/config')
-const { types, defaults, shorthands } = require('../../lib/utils/config.js')
+const { definitions, shorthands, flatten } = require('../../lib/utils/config')
const freshConfig = (opts = {}) => {
for (const env of Object.keys(process.env).filter(e => /^npm_/.test(e)))
delete process.env[env]
@@ -50,12 +50,12 @@ const freshConfig = (opts = {}) => {
process.env.npm_config_cache = CACHE
npm.config = new Config({
- types,
- defaults,
+ definitions,
shorthands,
npmPath,
log: npmlog,
...opts,
+ flatten,
})
}
@@ -145,6 +145,7 @@ t.test('npm.load', t => {
t.equal(npm.loading, false, 'not loading yet')
const p = npm.load(first).then(() => {
+ t.ok(npm.usage, 'has usage')
npm.config.set('prefix', dir)
t.match(npm, {
loaded: true,
@@ -160,7 +161,7 @@ t.test('npm.load', t => {
npm.load(third)
t.equal(thirdCalled, true, 'third callbback got called')
t.match(logs, [
- ['timing', 'npm:load', /Completed in [0-9]+ms/],
+ ['timing', 'npm:load', /Completed in [0-9.]+ms/],
])
logs.length = 0
@@ -289,6 +290,11 @@ t.test('npm.load', t => {
t.equal(npm.config.get('scope'), '@foo', 'added the @ sign to scope')
t.match(logs.filter(l => l[0] !== 'timing' || !/^config:/.test(l[1])), [
[
+ 'timing',
+ 'npm:load:whichnode',
+ /Completed in [0-9.]+ms/,
+ ],
+ [
'verbose',
'node symlink',
resolve(dir, 'bin', node),
@@ -296,7 +302,7 @@ t.test('npm.load', t => {
[
'timing',
'npm:load',
- /Completed in [0-9]+ms/,
+ /Completed in [0-9.]+ms/,
],
])
logs.length = 0
@@ -307,6 +313,9 @@ t.test('npm.load', t => {
if (er)
throw er
+ t.equal(npm.command, 'll', 'command set to first npm command')
+ t.equal(npm.flatOptions.npmCommand, 'll', 'npmCommand flatOption set')
+
t.same(consoleLogs, [[npm.commands.ll.usage]], 'print usage')
consoleLogs.length = 0
npm.config.set('usage', false)
@@ -318,6 +327,9 @@ t.test('npm.load', t => {
if (er)
throw er
+ t.strictSame([npm.command, npm.flatOptions.npmCommand], ['ll', 'll'],
+ 'does not change npm.command when another command is called')
+
t.match(logs, [
[
'error',
@@ -328,12 +340,12 @@ t.test('npm.load', t => {
[
'timing',
'command:config',
- /Completed in [0-9]+ms/,
+ /Completed in [0-9.]+ms/,
],
[
'timing',
'command:get',
- /Completed in [0-9]+ms/,
+ /Completed in [0-9.]+ms/,
],
])
t.same(consoleLogs, [['scope=@foo\n\u2010not-a-dash=undefined']])
@@ -343,6 +355,84 @@ t.test('npm.load', t => {
await new Promise((res) => setTimeout(res))
})
+ t.test('workpaces-aware configs and commands', async t => {
+ const dir = t.testdir({
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ scripts: { test: 'echo test a' },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ scripts: { test: 'echo test b' },
+ }),
+ },
+ },
+ 'package.json': JSON.stringify({
+ name: 'root',
+ version: '1.0.0',
+ workspaces: ['./packages/*'],
+ }),
+ '.npmrc': '',
+ })
+
+ const { log } = console
+ const consoleLogs = []
+ console.log = (...msg) => consoleLogs.push(msg)
+
+ const { execPath } = process
+ t.teardown(() => {
+ console.log = log
+ })
+
+ freshConfig({
+ argv: [
+ execPath,
+ process.argv[1],
+ '--userconfig',
+ resolve(dir, '.npmrc'),
+ '--color',
+ 'false',
+ '--workspaces',
+ 'true',
+ ],
+ })
+
+ await npm.load(er => {
+ if (er)
+ throw er
+ })
+
+ npm.localPrefix = dir
+
+ await new Promise((res, rej) => {
+ npm.commands['run-script']([], er => {
+ if (er)
+ rej(er)
+
+ t.match(
+ consoleLogs,
+ [
+ ['Lifecycle scripts included in a@1.0.0:'],
+ [' test\n echo test a'],
+ [''],
+ ['Lifecycle scripts included in b@1.0.0:'],
+ [' test\n echo test b'],
+ [''],
+ ],
+ 'should exec workspaces version of commands'
+ )
+
+ res()
+ })
+ })
+ })
+
t.end()
})
diff --git a/deps/npm/test/lib/outdated.js b/deps/npm/test/lib/outdated.js
index 02952971b6..5aff7c37ac 100644
--- a/deps/npm/test/lib/outdated.js
+++ b/deps/npm/test/lib/outdated.js
@@ -1,5 +1,6 @@
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const packument = spec => {
const mocks = {
@@ -89,12 +90,13 @@ const outdated = (dir, opts) => {
packument,
},
})
- return new Outdated({
+ const npm = mockNpm({
+ ...opts,
prefix: dir,
globalDir: `${globalDir}/node_modules`,
- flatOptions: opts,
output,
})
+ return new Outdated(npm)
}
t.beforeEach((done) => {
@@ -173,7 +175,7 @@ t.test('should display outdated deps', t => {
t.test('outdated global', t => {
outdated(null, {
- global: true,
+ config: { global: true },
}).exec([], () => {
t.matchSnapshot(logs)
t.end()
@@ -182,7 +184,9 @@ t.test('should display outdated deps', t => {
t.test('outdated', t => {
outdated(testDir, {
- global: false,
+ config: {
+ global: false,
+ },
color: true,
}).exec([], () => {
t.matchSnapshot(logs)
@@ -192,9 +196,11 @@ t.test('should display outdated deps', t => {
t.test('outdated --omit=dev', t => {
outdated(testDir, {
- global: false,
+ config: {
+ global: false,
+ omit: ['dev'],
+ },
color: true,
- omit: ['dev'],
}).exec([], () => {
t.matchSnapshot(logs)
t.end()
@@ -203,9 +209,11 @@ t.test('should display outdated deps', t => {
t.test('outdated --omit=dev --omit=peer', t => {
outdated(testDir, {
- global: false,
+ config: {
+ global: false,
+ omit: ['dev', 'peer'],
+ },
color: true,
- omit: ['dev', 'peer'],
}).exec([], () => {
t.matchSnapshot(logs)
t.end()
@@ -214,9 +222,11 @@ t.test('should display outdated deps', t => {
t.test('outdated --omit=prod', t => {
outdated(testDir, {
- global: false,
+ config: {
+ global: false,
+ omit: ['prod'],
+ },
color: true,
- omit: ['prod'],
}).exec([], () => {
t.matchSnapshot(logs)
t.end()
@@ -225,8 +235,10 @@ t.test('should display outdated deps', t => {
t.test('outdated --long', t => {
outdated(testDir, {
- global: false,
- long: true,
+ config: {
+ global: false,
+ long: true,
+ },
}).exec([], () => {
t.matchSnapshot(logs)
t.end()
@@ -235,8 +247,10 @@ t.test('should display outdated deps', t => {
t.test('outdated --json', t => {
outdated(testDir, {
- global: false,
- json: true,
+ config: {
+ global: false,
+ json: true,
+ },
}).exec([], () => {
t.matchSnapshot(logs)
t.end()
@@ -245,9 +259,11 @@ t.test('should display outdated deps', t => {
t.test('outdated --json --long', t => {
outdated(testDir, {
- global: false,
- json: true,
- long: true,
+ config: {
+ global: false,
+ json: true,
+ long: true,
+ },
}).exec([], () => {
t.matchSnapshot(logs)
t.end()
@@ -256,8 +272,10 @@ t.test('should display outdated deps', t => {
t.test('outdated --parseable', t => {
outdated(testDir, {
- global: false,
- parseable: true,
+ config: {
+ global: false,
+ parseable: true,
+ },
}).exec([], () => {
t.matchSnapshot(logs)
t.end()
@@ -266,9 +284,11 @@ t.test('should display outdated deps', t => {
t.test('outdated --parseable --long', t => {
outdated(testDir, {
- global: false,
- parseable: true,
- long: true,
+ config: {
+ global: false,
+ parseable: true,
+ long: true,
+ },
}).exec([], () => {
t.matchSnapshot(logs)
t.end()
@@ -277,7 +297,9 @@ t.test('should display outdated deps', t => {
t.test('outdated --all', t => {
outdated(testDir, {
- all: true,
+ config: {
+ all: true,
+ },
}).exec([], () => {
t.matchSnapshot(logs)
t.end()
@@ -286,7 +308,9 @@ t.test('should display outdated deps', t => {
t.test('outdated specific dep', t => {
outdated(testDir, {
- global: false,
+ config: {
+ global: false,
+ },
}).exec(['alpha'], () => {
t.matchSnapshot(logs)
t.end()
diff --git a/deps/npm/test/lib/pack.js b/deps/npm/test/lib/pack.js
index ce319be76b..a5163acfdc 100644
--- a/deps/npm/test/lib/pack.js
+++ b/deps/npm/test/lib/pack.js
@@ -1,5 +1,6 @@
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const OUTPUT = []
const output = (...msg) => OUTPUT.push(msg)
@@ -25,14 +26,15 @@ t.test('should pack current directory with no arguments', (t) => {
clearProgress: () => {},
},
})
- const pack = new Pack({
- flatOptions: {
+ const npm = mockNpm({
+ config: {
unicode: false,
json: false,
- dryRun: false,
+ 'dry-run': false,
},
output,
})
+ const pack = new Pack(npm)
pack.exec([], er => {
if (er)
@@ -60,14 +62,15 @@ t.test('should pack given directory', (t) => {
clearProgress: () => {},
},
})
- const pack = new Pack({
- flatOptions: {
+ const npm = mockNpm({
+ config: {
unicode: true,
json: true,
- dryRun: true,
+ 'dry-run': true,
},
output,
})
+ const pack = new Pack(npm)
pack.exec([testDir], er => {
if (er)
@@ -95,14 +98,15 @@ t.test('should pack given directory for scoped package', (t) => {
clearProgress: () => {},
},
})
- const pack = new Pack({
- flatOptions: {
+ const npm = mockNpm({
+ config: {
unicode: true,
json: true,
- dryRun: true,
+ 'dry-run': true,
},
output,
})
+ const pack = new Pack(npm)
return pack.exec([testDir], er => {
if (er)
@@ -129,14 +133,15 @@ t.test('should log pack contents', (t) => {
clearProgress: () => {},
},
})
- const pack = new Pack({
- flatOptions: {
+ const npm = mockNpm({
+ config: {
unicode: false,
json: false,
- dryRun: false,
+ 'dry-run': false,
},
output,
})
+ const pack = new Pack(npm)
pack.exec([], er => {
if (er)
diff --git a/deps/npm/test/lib/ping.js b/deps/npm/test/lib/ping.js
index f3563036f7..95361035ac 100644
--- a/deps/npm/test/lib/ping.js
+++ b/deps/npm/test/lib/ping.js
@@ -1,14 +1,15 @@
const { test } = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
test('pings', (t) => {
t.plan(8)
- const flatOptions = { registry: 'https://registry.npmjs.org' }
+ const registry = 'https://registry.npmjs.org'
let noticeCalls = 0
const Ping = requireInject('../../lib/ping.js', {
'../../lib/utils/ping.js': function (spec) {
- t.equal(spec, flatOptions, 'passes flatOptions')
+ t.equal(spec.registry, registry, 'passes flatOptions')
return {}
},
npmlog: {
@@ -16,7 +17,7 @@ test('pings', (t) => {
++noticeCalls
if (noticeCalls === 1) {
t.equal(type, 'PING', 'should log a PING')
- t.equal(spec, flatOptions.registry, 'should log the registry url')
+ t.equal(spec, registry, 'should log the registry url')
} else {
t.equal(type, 'PONG', 'should log a PONG')
t.match(spec, /\d+ms/, 'should log the elapsed milliseconds')
@@ -24,7 +25,11 @@ test('pings', (t) => {
},
},
})
- const ping = new Ping({ flatOptions })
+ const npm = mockNpm({
+ config: { registry },
+ flatOptions: { registry },
+ })
+ const ping = new Ping(npm)
ping.exec([], (err) => {
t.equal(noticeCalls, 2, 'should have logged 2 lines')
@@ -36,12 +41,12 @@ test('pings', (t) => {
test('pings and logs details', (t) => {
t.plan(10)
- const flatOptions = { registry: 'https://registry.npmjs.org' }
+ const registry = 'https://registry.npmjs.org'
const details = { extra: 'data' }
let noticeCalls = 0
const Ping = requireInject('../../lib/ping.js', {
'../../lib/utils/ping.js': function (spec) {
- t.equal(spec, flatOptions, 'passes flatOptions')
+ t.equal(spec.registry, registry, 'passes flatOptions')
return details
},
npmlog: {
@@ -49,7 +54,7 @@ test('pings and logs details', (t) => {
++noticeCalls
if (noticeCalls === 1) {
t.equal(type, 'PING', 'should log a PING')
- t.equal(spec, flatOptions.registry, 'should log the registry url')
+ t.equal(spec, registry, 'should log the registry url')
} else if (noticeCalls === 2) {
t.equal(type, 'PONG', 'should log a PONG')
t.match(spec, /\d+ms/, 'should log the elapsed milliseconds')
@@ -61,7 +66,11 @@ test('pings and logs details', (t) => {
},
},
})
- const ping = new Ping({ flatOptions })
+ const npm = mockNpm({
+ config: { registry },
+ flatOptions: { registry },
+ })
+ const ping = new Ping(npm)
ping.exec([], (err) => {
t.equal(noticeCalls, 3, 'should have logged 3 lines')
@@ -73,12 +82,12 @@ test('pings and logs details', (t) => {
test('pings and returns json', (t) => {
t.plan(11)
- const flatOptions = { registry: 'https://registry.npmjs.org', json: true }
+ const registry = 'https://registry.npmjs.org'
const details = { extra: 'data' }
let noticeCalls = 0
const Ping = requireInject('../../lib/ping.js', {
'../../lib/utils/ping.js': function (spec) {
- t.equal(spec, flatOptions, 'passes flatOptions')
+ t.equal(spec.registry, registry, 'passes flatOptions')
return details
},
npmlog: {
@@ -86,7 +95,7 @@ test('pings and returns json', (t) => {
++noticeCalls
if (noticeCalls === 1) {
t.equal(type, 'PING', 'should log a PING')
- t.equal(spec, flatOptions.registry, 'should log the registry url')
+ t.equal(spec, registry, 'should log the registry url')
} else {
t.equal(type, 'PONG', 'should log a PONG')
t.match(spec, /\d+ms/, 'should log the elapsed milliseconds')
@@ -94,15 +103,17 @@ test('pings and returns json', (t) => {
},
},
})
- const ping = new Ping({
- flatOptions,
+ const npm = mockNpm({
+ config: { registry, json: true },
+ flatOptions: { registry },
output: function (spec) {
const parsed = JSON.parse(spec)
- t.equal(parsed.registry, flatOptions.registry, 'returns the correct registry url')
+ t.equal(parsed.registry, registry, 'returns the correct registry url')
t.match(parsed.details, details, 'prints returned details')
t.type(parsed.time, 'number', 'returns time as a number')
},
})
+ const ping = new Ping(npm)
ping.exec([], (err) => {
t.equal(noticeCalls, 2, 'should have logged 2 lines')
diff --git a/deps/npm/test/lib/profile.js b/deps/npm/test/lib/profile.js
index d1be93b0cb..5b1210615a 100644
--- a/deps/npm/test/lib/profile.js
+++ b/deps/npm/test/lib/profile.js
@@ -1,20 +1,24 @@
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
let result = ''
-const flatOptions = {
+const config = {
otp: '',
json: false,
parseable: false,
registry: 'https://registry.npmjs.org/',
}
-const npm = {
- config: {},
- flatOptions: { ...flatOptions },
+const flatOptions = {
+ registry: 'https://registry.npmjs.org/',
+}
+const npm = mockNpm({
+ config,
+ flatOptions,
output: (...msg) => {
result = result ? `${result}\n${msg.join('\n')}` : msg.join('\n')
},
-}
+})
const mocks = {
ansistyles: { bright: a => a },
npmlog: {
@@ -65,8 +69,10 @@ const userProfile = {
t.afterEach(cb => {
result = ''
- npm.config = {}
- npm.flatOptions = { ...flatOptions }
+ flatOptions.otp = ''
+ config.json = false
+ config.parseable = false
+ config.registry = 'https://registry.npmjs.org/'
cb()
})
@@ -111,7 +117,7 @@ t.test('profile get no args', t => {
})
t.test('--json', t => {
- npm.flatOptions.json = true
+ config.json = true
profile.exec(['get'], err => {
if (err)
@@ -127,7 +133,7 @@ t.test('profile get no args', t => {
})
t.test('--parseable', t => {
- npm.flatOptions.parseable = true
+ config.parseable = true
profile.exec(['get'], err => {
if (err)
@@ -256,7 +262,7 @@ t.test('profile get <key>', t => {
})
t.test('--json', t => {
- npm.flatOptions.json = true
+ config.json = true
profile.exec(['get', 'name'], err => {
if (err)
@@ -272,7 +278,7 @@ t.test('profile get <key>', t => {
})
t.test('--parseable', t => {
- npm.flatOptions.parseable = true
+ config.parseable = true
profile.exec(['get', 'name'], err => {
if (err)
@@ -316,7 +322,7 @@ t.test('profile get multiple args', t => {
})
t.test('--json', t => {
- npm.flatOptions.json = true
+ config.json = true
profile.exec(['get', 'name', 'email', 'github'], err => {
if (err)
@@ -332,7 +338,7 @@ t.test('profile get multiple args', t => {
})
t.test('--parseable', t => {
- npm.flatOptions.parseable = true
+ config.parseable = true
profile.exec(['get', 'name', 'email', 'github'], err => {
if (err)
@@ -451,7 +457,7 @@ t.test('profile set <key> <value>', t => {
t.test('--json', t => {
t.plan(2)
- npm.flatOptions.json = true
+ config.json = true
const Profile = requireInject('../../lib/profile.js', {
...mocks,
@@ -476,7 +482,7 @@ t.test('profile set <key> <value>', t => {
t.test('--parseable', t => {
t.plan(2)
- npm.flatOptions.parseable = true
+ config.parseable = true
const Profile = requireInject('../../lib/profile.js', {
...mocks,
@@ -705,7 +711,7 @@ t.test('enable-2fa', t => {
})
t.test('no support for --json output', t => {
- npm.flatOptions.json = true
+ config.json = true
profile.exec(['enable-2fa', 'auth-only'], err => {
t.match(
@@ -719,7 +725,7 @@ t.test('enable-2fa', t => {
})
t.test('no support for --parseable output', t => {
- npm.flatOptions.parseable = true
+ config.parseable = true
profile.exec(['enable-2fa', 'auth-only'], err => {
t.match(
@@ -817,18 +823,16 @@ t.test('enable-2fa', t => {
t.plan(10)
// mock legacy basic auth style
- npm.config = {
- getCredentialsByURI (reg) {
- t.equal(reg, flatOptions.registry, 'should use expected registry')
- return { auth: Buffer.from('foo:bar').toString('base64') }
- },
- setCredentialsByURI (registry, { token }) {
- t.equal(registry, flatOptions.registry, 'should set expected registry')
- t.equal(token, 'token', 'should set expected token')
- },
- save (type) {
- t.equal(type, 'user', 'should save to user config')
- },
+ npm.config.getCredentialsByURI = (reg) => {
+ t.equal(reg, flatOptions.registry, 'should use expected registry')
+ return { auth: Buffer.from('foo:bar').toString('base64') }
+ }
+ npm.config.setCredentialsByURI = (registry, { token }) => {
+ t.equal(registry, flatOptions.registry, 'should set expected registry')
+ t.equal(token, 'token', 'should set expected token')
+ }
+ npm.config.save = (type) => {
+ t.equal(type, 'user', 'should save to user config')
}
const npmProfile = {
@@ -901,12 +905,10 @@ t.test('enable-2fa', t => {
t.test('from token and set otp, retries on pending and verifies with qrcode', t => {
t.plan(4)
- npm.flatOptions.otp = '1234'
+ flatOptions.otp = '1234'
- npm.config = {
- getCredentialsByURI () {
- return { token: 'token' }
- },
+ npm.config.getCredentialsByURI = () => {
+ return { token: 'token' }
}
let setCount = 0
@@ -1003,12 +1005,10 @@ t.test('enable-2fa', t => {
})
t.test('from token and set otp, retrieves invalid otp', t => {
- npm.flatOptions.otp = '1234'
+ flatOptions.otp = '1234'
- npm.config = {
- getCredentialsByURI () {
- return { token: 'token' }
- },
+ npm.config.getCredentialsByURI = () => {
+ return { token: 'token' }
}
const npmProfile = {
@@ -1055,12 +1055,11 @@ t.test('enable-2fa', t => {
})
t.test('from token auth provides --otp config arg', t => {
- npm.flatOptions.otp = '123456'
+ flatOptions.otp = '123456'
+ flatOptions.otp = '123456'
- npm.config = {
- getCredentialsByURI (reg) {
- return { token: 'token' }
- },
+ npm.config.getCredentialsByURI = (reg) => {
+ return { token: 'token' }
}
const npmProfile = {
@@ -1105,10 +1104,8 @@ t.test('enable-2fa', t => {
})
t.test('missing tfa from user profile', t => {
- npm.config = {
- getCredentialsByURI (reg) {
- return { token: 'token' }
- },
+ npm.config.getCredentialsByURI = (reg) => {
+ return { token: 'token' }
}
const npmProfile = {
@@ -1156,10 +1153,8 @@ t.test('enable-2fa', t => {
})
t.test('defaults to auth-and-writes permission if no mode specified', t => {
- npm.config = {
- getCredentialsByURI (reg) {
- return { token: 'token' }
- },
+ npm.config.getCredentialsByURI = (reg) => {
+ return { token: 'token' }
}
const npmProfile = {
@@ -1303,7 +1298,7 @@ t.test('disable-2fa', t => {
})
t.test('--json', t => {
- npm.flatOptions.json = true
+ config.json = true
const Profile = requireInject('../../lib/profile.js', {
...mocks,
@@ -1326,7 +1321,7 @@ t.test('disable-2fa', t => {
})
t.test('--parseable', t => {
- npm.flatOptions.parseable = true
+ config.parseable = true
const Profile = requireInject('../../lib/profile.js', {
...mocks,
@@ -1354,7 +1349,7 @@ t.test('disable-2fa', t => {
t.test('--otp config already set', t => {
t.plan(3)
- npm.flatOptions.otp = '123456'
+ flatOptions.otp = '123456'
const npmProfile = {
async get () {
diff --git a/deps/npm/test/lib/publish.js b/deps/npm/test/lib/publish.js
index 6337a1fcf0..f61377b54f 100644
--- a/deps/npm/test/lib/publish.js
+++ b/deps/npm/test/lib/publish.js
@@ -1,5 +1,6 @@
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const fs = require('fs')
// The way we set loglevel is kind of convoluted, and there is no way to affect
@@ -10,11 +11,13 @@ const log = require('npmlog')
log.level = 'silent'
// mock config
-const {defaults} = require('../../lib/utils/config.js')
+const {definitions} = require('../../lib/utils/config')
+const defaults = Object.entries(definitions).reduce((defaults, [key, def]) => {
+ defaults[key] = def.default
+ return defaults
+}, {})
-const config = {
- list: [defaults],
-}
+const config = defaults
t.afterEach(cb => {
log.level = 'silent'
@@ -54,18 +57,17 @@ t.test('should publish with libnpmpublish, passing through flatOptions and respe
},
},
})
- const publish = new Publish({
+ const npm = mockNpm({
+ config,
flatOptions: {
customValue: true,
},
- config: {
- ...config,
- getCredentialsByURI: (uri) => {
- t.same(uri, registry, 'gets credentials for expected registry')
- return { token: 'some.registry.token' }
- },
- },
})
+ npm.config.getCredentialsByURI = (uri) => {
+ t.same(uri, registry, 'gets credentials for expected registry')
+ return { token: 'some.registry.token' }
+ }
+ const publish = new Publish(npm)
publish.exec([testDir], (er) => {
if (er)
@@ -104,15 +106,12 @@ 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' }
- },
- },
- })
+ const npm = mockNpm({ config })
+ npm.config.getCredentialsByURI = (uri) => {
+ t.same(uri, registry, 'gets credentials for expected registry')
+ return { token: 'some.registry.token' }
+ }
+ const publish = new Publish(npm)
publish.exec([testDir], (er) => {
if (er)
@@ -148,21 +147,17 @@ 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' }
- },
- },
+ const npm = mockNpm({
+ config: { ...config, json: true },
output: () => {
t.pass('output is called')
},
})
+ npm.config.getCredentialsByURI = (uri) => {
+ t.same(uri, defaults.registry, 'gets credentials for expected registry')
+ return { token: 'some.registry.token' }
+ }
+ const publish = new Publish(npm)
publish.exec([testDir], (er) => {
if (er)
@@ -198,20 +193,17 @@ 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')
- },
- },
+ const npm = mockNpm({
+ config: { ...config, 'dry-run': true },
output: () => {
throw new Error('should not output in dry run mode')
},
})
+ npm.config.getCredentialsByURI = () => {
+ throw new Error('should not call getCredentialsByURI in dry run')
+ }
+
+ const publish = new Publish(npm)
publish.exec([testDir], (er) => {
if (er)
@@ -247,20 +239,16 @@ 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')
- },
- },
+ const npm = mockNpm({
+ config: { ...config, 'dry-run': true },
output: () => {
t.pass('output fn is called')
},
})
+ npm.config.getCredentialsByURI = () => {
+ throw new Error('should not call getCredentialsByURI in dry run')
+ }
+ const publish = new Publish(npm)
publish.exec([testDir], (er) => {
if (er)
@@ -285,12 +273,10 @@ t.test('throws when invalid tag', (t) => {
t.plan(1)
const Publish = requireInject('../../lib/publish.js')
- const publish = new Publish({
- flatOptions: {
- defaultTag: '0.0.13',
- },
- config,
+ const npm = mockNpm({
+ config: { ...config, tag: '0.0.13' },
})
+ const publish = new Publish(npm)
publish.exec([], (err) => {
t.match(err, {
@@ -331,15 +317,12 @@ 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' }
- },
- },
- })
+ const npm = mockNpm({ config })
+ npm.config.getCredentialsByURI = (uri) => {
+ t.same(uri, defaults.registry, 'gets credentials for expected registry')
+ return { token: 'some.registry.token' }
+ }
+ const publish = new Publish(npm)
publish.exec([`${testDir}/tarball/package.tgz`], (er) => {
if (er)
@@ -352,15 +335,12 @@ t.test('can publish a tarball', t => {
t.test('should check auth for default registry', t => {
t.plan(2)
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 {}
- },
- },
- })
+ const npm = mockNpm({ config })
+ npm.config.getCredentialsByURI = (uri) => {
+ t.same(uri, defaults.registry, 'gets credentials for expected registry')
+ return {}
+ }
+ const publish = new Publish(npm)
publish.exec([], (err) => {
t.match(err, {
@@ -375,18 +355,15 @@ t.test('should check auth for configured registry', t => {
t.plan(2)
const registry = 'https://some.registry'
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 {}
- },
- },
+ const npm = mockNpm({
+ config,
+ flatOptions: { registry },
})
+ npm.config.getCredentialsByURI = (uri) => {
+ t.same(uri, registry, 'gets credentials for expected registry')
+ return {}
+ }
+ const publish = new Publish(npm)
publish.exec([], (err) => {
t.match(err, {
@@ -408,18 +385,15 @@ t.test('should check auth for scope specific registry', t => {
})
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 {}
- },
- },
+ const npm = mockNpm({
+ config,
+ flatOptions: { '@npm:registry': registry },
})
+ npm.config.getCredentialsByURI = (uri) => {
+ t.same(uri, registry, 'gets credentials for expected registry')
+ return {}
+ }
+ const publish = new Publish(npm)
publish.exec([testDir], (err) => {
t.match(err, {
@@ -448,18 +422,16 @@ t.test('should use auth for scope specific registry', t => {
},
},
})
- 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' }
- },
- },
+ const npm = mockNpm({
+ config,
+ flatOptions: { '@npm:registry': registry },
})
+ npm.config.getCredentialsByURI = (uri) => {
+ t.same(uri, registry, 'gets credentials for expected registry')
+ return { token: 'some.registry.token' }
+ }
+ const publish = new Publish(npm)
+
publish.exec([testDir], (er) => {
if (er)
throw er
@@ -489,9 +461,60 @@ t.test('read registry only from publishConfig', t => {
},
},
})
+ const npm = mockNpm({
+ config,
+ })
+ npm.config.getCredentialsByURI = (uri) => {
+ t.same(uri, registry, 'gets credentials for expected registry')
+ return { token: 'some.registry.token' }
+ }
+ const publish = new Publish(npm)
+
+ publish.exec([testDir], (er) => {
+ if (er)
+ throw er
+ t.pass('got to callback')
+ t.end()
+ })
+})
+
+t.test('able to publish after if encountered multiple configs', t => {
+ t.plan(3)
+
+ const registry = 'https://some.registry'
+ const tag = 'better-tag'
+ const publishConfig = { registry }
+ const testDir = t.testdir({
+ 'package.json': JSON.stringify({
+ name: 'my-cool-pkg',
+ version: '1.0.0',
+ publishConfig,
+ }, null, 2),
+ })
+
+ const configList = [defaults]
+ configList.unshift(Object.assign(Object.create(configList[0]), {
+ registry: `https://other.registry`,
+ tag: 'some-tag',
+ }))
+ configList.unshift(Object.assign(Object.create(configList[0]), { tag }))
+
+ const Publish = requireInject('../../lib/publish.js', {
+ libnpmpublish: {
+ publish: (manifest, tarData, opts) => {
+ t.same(opts.defaultTag, tag, 'gets option for expected tag')
+ },
+ },
+ })
const publish = new Publish({
+ // what would be flattened by the configList created above
+ flatOptions: {
+ defaultTag: 'better-tag',
+ registry: 'https://other.registry',
+ },
config: {
- ...config,
+ get: key => configList[0][key],
+ list: configList,
getCredentialsByURI: (uri) => {
t.same(uri, registry, 'gets credentials for expected registry')
return { token: 'some.registry.token' }
diff --git a/deps/npm/test/lib/rebuild.js b/deps/npm/test/lib/rebuild.js
index 1eb45e0d1d..6e144b7e11 100644
--- a/deps/npm/test/lib/rebuild.js
+++ b/deps/npm/test/lib/rebuild.js
@@ -1,25 +1,27 @@
const fs = require('fs')
const { resolve } = require('path')
+const mockNpm = require('../fixtures/mock-npm')
const t = require('tap')
let result = ''
-const npm = {
+const config = {
+ global: false,
+}
+const npm = mockNpm({
globalDir: '',
- flatOptions: {
- global: false,
- },
+ config,
prefix: '',
output: (...msg) => {
result += msg.join('\n')
},
-}
+})
const Rebuild = require('../../lib/rebuild.js')
const rebuild = new Rebuild(npm)
t.afterEach(cb => {
npm.prefix = ''
- npm.flatOptions.global = false
+ config.global = false
npm.globalDir = ''
result = ''
cb()
@@ -34,7 +36,7 @@ t.test('no args', t => {
version: '1.0.0',
bin: 'cwd',
scripts: {
- preinstall: `node -e 'require("fs").writeFileSync("cwd", "")'`,
+ preinstall: "node -e \"require('fs').writeFileSync('cwd', '')\"",
},
}),
},
@@ -44,7 +46,7 @@ t.test('no args', t => {
version: '1.0.0',
bin: 'cwd',
scripts: {
- preinstall: `node -e 'require("fs").writeFileSync("cwd", "")'`,
+ preinstall: "node -e \"require('fs').writeFileSync('cwd', '')\"",
},
}),
},
@@ -237,7 +239,7 @@ t.test('global prefix', t => {
},
})
- npm.flatOptions.global = true
+ config.global = true
npm.globalDir = resolve(globalPath, 'lib', 'node_modules')
rebuild.exec([], err => {
diff --git a/deps/npm/test/lib/run-script.js b/deps/npm/test/lib/run-script.js
index 0566daf234..f7eb46fedf 100644
--- a/deps/npm/test/lib/run-script.js
+++ b/deps/npm/test/lib/run-script.js
@@ -1,37 +1,60 @@
+const { resolve } = require('path')
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
+
+const normalizePath = p => p
+ .replace(/\\+/g, '/')
+ .replace(/\r\n/g, '\n')
+
+const cleanOutput = (str) => normalizePath(str)
+ .replace(normalizePath(process.cwd()), '{CWD}')
const RUN_SCRIPTS = []
-const npm = {
+const flatOptions = {
+ scriptShell: undefined,
+}
+const config = {
+ json: false,
+ parseable: false,
+ 'if-present': false,
+}
+
+const npm = mockNpm({
localPrefix: __dirname,
- flatOptions: {
- scriptShell: undefined,
- json: false,
- parseable: false,
- },
- config: {
- settings: {
- 'if-present': false,
+ flatOptions,
+ config,
+ commands: {
+ help: {
+ description: 'test help description',
},
- get: k => npm.config.settings[k],
- set: (k, v) => {
- npm.config.settings[k] = v
+ test: {
+ description: 'test test description',
},
},
output: (...msg) => output.push(msg),
-}
+})
const output = []
+const npmlog = {
+ disableProgress: () => null,
+ level: 'warn',
+ error: () => null,
+}
+
t.afterEach(cb => {
+ npm.color = false
+ npmlog.level = 'warn'
+ npmlog.error = () => null
output.length = 0
RUN_SCRIPTS.length = 0
- npm.flatOptions.json = false
- npm.flatOptions.parseable = false
+ config['if-present'] = false
+ config.json = false
+ config.parseable = false
cb()
})
-const npmlog = { level: 'warn' }
const getRS = windows => {
const RunScript = requireInject('../../lib/run-script.js', {
'@npmcli/run-script': Object.assign(async opts => {
@@ -261,26 +284,41 @@ t.test('try to run missing script', t => {
npm.localPrefix = t.testdir({
'package.json': JSON.stringify({
scripts: { hello: 'world' },
+ bin: { goodnight: 'moon' },
}),
})
t.test('no suggestions', t => {
runScript.exec(['notevenclose'], er => {
t.match(er, {
- message: 'missing script: notevenclose',
+ message: 'Missing script: "notevenclose"',
})
t.end()
})
})
- t.test('suggestions', t => {
+ t.test('script suggestions', t => {
runScript.exec(['helo'], er => {
t.match(er, {
- message: 'missing script: helo\n\nDid you mean this?\n hello',
+ message: 'Missing script: "helo"',
+ })
+ t.match(er, {
+ message: 'npm run hello',
+ })
+ t.end()
+ })
+ })
+ t.test('bin suggestions', t => {
+ runScript.exec(['goodneght'], er => {
+ t.match(er, {
+ message: 'Missing script: "goodneght"',
+ })
+ t.match(er, {
+ message: 'npm exec goodnight',
})
t.end()
})
})
t.test('with --if-present', t => {
- npm.config.set('if-present', true)
+ config['if-present'] = true
runScript.exec(['goodbye'], er => {
if (er)
throw er
@@ -331,7 +369,7 @@ t.test('run pre/post hooks', t => {
})
t.test('skip pre/post hooks when using ignoreScripts', t => {
- npm.flatOptions.ignoreScripts = true
+ config['ignore-scripts'] = true
npm.localPrefix = t.testdir({
'package.json': JSON.stringify({
@@ -368,7 +406,7 @@ t.test('skip pre/post hooks when using ignoreScripts', t => {
},
])
t.end()
- delete npm.flatOptions.ignoreScripts
+ delete config['ignore-scripts']
})
})
@@ -443,13 +481,14 @@ t.test('list scripts', t => {
if (er)
throw er
t.strictSame(output, [
- ['Lifecycle scripts included in x:'],
+ ['Lifecycle scripts included in x@1.2.3:'],
[' 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()
})
@@ -466,7 +505,7 @@ t.test('list scripts', t => {
})
t.test('warn json', t => {
npmlog.level = 'warn'
- npm.flatOptions.json = true
+ config.json = true
runScript.exec([], er => {
if (er)
throw er
@@ -476,7 +515,7 @@ t.test('list scripts', t => {
})
t.test('parseable', t => {
- npm.flatOptions.parseable = true
+ config.parseable = true
runScript.exec([], er => {
if (er)
throw er
@@ -522,8 +561,9 @@ t.test('list scripts, only commands', t => {
if (er)
throw er
t.strictSame(output, [
- ['Lifecycle scripts included in x:'],
+ ['Lifecycle scripts included in x@1.2.3:'],
[' preversion\n echo doing the version dance'],
+ [''],
])
t.end()
})
@@ -542,9 +582,443 @@ t.test('list scripts, only non-commands', t => {
if (er)
throw er
t.strictSame(output, [
- ['Scripts available in x via `npm run-script`:'],
+ ['Scripts available in x@1.2.3 via `npm run-script`:'],
[' glorp\n echo doing the glerp glop'],
+ [''],
])
t.end()
})
})
+
+t.test('workspaces', t => {
+ npm.localPrefix = t.testdir({
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ scripts: { glorp: 'echo a doing the glerp glop' },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '2.0.0',
+ scripts: { glorp: 'echo b doing the glerp glop' },
+ }),
+ },
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ scripts: {
+ test: 'exit 0',
+ posttest: 'echo posttest',
+ lorem: 'echo c lorem',
+ },
+ }),
+ },
+ d: {
+ 'package.json': JSON.stringify({
+ name: 'd',
+ version: '1.0.0',
+ scripts: {
+ test: 'exit 0',
+ posttest: 'echo posttest',
+ },
+ }),
+ },
+ e: {
+ 'package.json': JSON.stringify({
+ name: 'e',
+ scripts: { test: 'exit 0', start: 'echo start something' },
+ }),
+ },
+ noscripts: {
+ 'package.json': JSON.stringify({
+ name: 'noscripts',
+ version: '1.0.0',
+ }),
+ },
+ },
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ workspaces: ['packages/*'],
+ }),
+ })
+
+ t.test('list all scripts', t => {
+ runScript.execWorkspaces([], [], er => {
+ if (er)
+ throw er
+ t.strictSame(output, [
+ ['Scripts available in a@1.0.0 via `npm run-script`:'],
+ [' glorp\n echo a doing the glerp glop'],
+ [''],
+ ['Scripts available in b@2.0.0 via `npm run-script`:'],
+ [' glorp\n echo b doing the glerp glop'],
+ [''],
+ ['Lifecycle scripts included in c@1.0.0:'],
+ [' test\n exit 0'],
+ [' posttest\n echo posttest'],
+ ['\navailable via `npm run-script`:'],
+ [' lorem\n echo c lorem'],
+ [''],
+ ['Lifecycle scripts included in d@1.0.0:'],
+ [' test\n exit 0'],
+ [' posttest\n echo posttest'],
+ [''],
+ ['Lifecycle scripts included in e:'],
+ [' test\n exit 0'],
+ [' start\n echo start something'],
+ [''],
+ ])
+ t.end()
+ })
+ })
+
+ t.test('list regular scripts, filtered by name', t => {
+ runScript.execWorkspaces([], ['a', 'b'], er => {
+ if (er)
+ throw er
+ t.strictSame(output, [
+ ['Scripts available in a@1.0.0 via `npm run-script`:'],
+ [' glorp\n echo a doing the glerp glop'],
+ [''],
+ ['Scripts available in b@2.0.0 via `npm run-script`:'],
+ [' glorp\n echo b doing the glerp glop'],
+ [''],
+ ])
+ t.end()
+ })
+ })
+
+ t.test('list regular scripts, filtered by path', t => {
+ runScript.execWorkspaces([], ['./packages/a'], er => {
+ if (er)
+ throw er
+ t.strictSame(output, [
+ ['Scripts available in a@1.0.0 via `npm run-script`:'],
+ [' glorp\n echo a doing the glerp glop'],
+ [''],
+ ])
+ t.end()
+ })
+ })
+
+ t.test('list regular scripts, filtered by parent folder', t => {
+ runScript.execWorkspaces([], ['./packages'], er => {
+ if (er)
+ throw er
+ t.strictSame(output, [
+ ['Scripts available in a@1.0.0 via `npm run-script`:'],
+ [' glorp\n echo a doing the glerp glop'],
+ [''],
+ ['Scripts available in b@2.0.0 via `npm run-script`:'],
+ [' glorp\n echo b doing the glerp glop'],
+ [''],
+ ['Lifecycle scripts included in c@1.0.0:'],
+ [' test\n exit 0'],
+ [' posttest\n echo posttest'],
+ ['\navailable via `npm run-script`:'],
+ [' lorem\n echo c lorem'],
+ [''],
+ ['Lifecycle scripts included in d@1.0.0:'],
+ [' test\n exit 0'],
+ [' posttest\n echo posttest'],
+ [''],
+ ['Lifecycle scripts included in e:'],
+ [' test\n exit 0'],
+ [' start\n echo start something'],
+ [''],
+ ])
+ t.end()
+ })
+ })
+
+ t.test('list all scripts with colors', t => {
+ npm.color = true
+ runScript.execWorkspaces([], [], er => {
+ if (er)
+ throw er
+ t.strictSame(output, [
+ [
+ '\u001b[1mScripts\u001b[22m available in \x1B[32ma@1.0.0\x1B[39m via `\x1B[34mnpm run-script\x1B[39m`:',
+ ],
+ [' glorp\n \x1B[2mecho a doing the glerp glop\x1B[22m'],
+ [''],
+ [
+ '\u001b[1mScripts\u001b[22m available in \x1B[32mb@2.0.0\x1B[39m via `\x1B[34mnpm run-script\x1B[39m`:',
+ ],
+ [' glorp\n \x1B[2mecho b doing the glerp glop\x1B[22m'],
+ [''],
+ [
+ '\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32mc@1.0.0\x1B[39m:',
+ ],
+ [' test\n \x1B[2mexit 0\x1B[22m'],
+ [' posttest\n \x1B[2mecho posttest\x1B[22m'],
+ ['\navailable via `\x1B[34mnpm run-script\x1B[39m`:'],
+ [' lorem\n \x1B[2mecho c lorem\x1B[22m'],
+ [''],
+ [
+ '\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32md@1.0.0\x1B[39m:',
+ ],
+ [' test\n \x1B[2mexit 0\x1B[22m'],
+ [' posttest\n \x1B[2mecho posttest\x1B[22m'],
+ [''],
+ [
+ '\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32me\x1B[39m:',
+ ],
+ [' test\n \x1B[2mexit 0\x1B[22m'],
+ [' start\n \x1B[2mecho start something\x1B[22m'],
+ [''],
+ ])
+ t.end()
+ })
+ })
+
+ t.test('list all scripts --json', t => {
+ config.json = true
+ runScript.execWorkspaces([], [], er => {
+ if (er)
+ throw er
+ t.strictSame(output, [
+ [
+ '{\n' +
+ ' "a": {\n' +
+ ' "glorp": "echo a doing the glerp glop"\n' +
+ ' },\n' +
+ ' "b": {\n' +
+ ' "glorp": "echo b doing the glerp glop"\n' +
+ ' },\n' +
+ ' "c": {\n' +
+ ' "test": "exit 0",\n' +
+ ' "posttest": "echo posttest",\n' +
+ ' "lorem": "echo c lorem"\n' +
+ ' },\n' +
+ ' "d": {\n' +
+ ' "test": "exit 0",\n' +
+ ' "posttest": "echo posttest"\n' +
+ ' },\n' +
+ ' "e": {\n' +
+ ' "test": "exit 0",\n' +
+ ' "start": "echo start something"\n' +
+ ' },\n' +
+ ' "noscripts": {}\n' +
+ '}',
+ ],
+ ])
+ t.end()
+ })
+ })
+
+ t.test('list all scripts --parseable', t => {
+ config.parseable = true
+ runScript.execWorkspaces([], [], er => {
+ if (er)
+ throw er
+ t.strictSame(output, [
+ ['a:glorp:echo a doing the glerp glop'],
+ ['b:glorp:echo b doing the glerp glop'],
+ ['c:test:exit 0'],
+ ['c:posttest:echo posttest'],
+ ['c:lorem:echo c lorem'],
+ ['d:test:exit 0'],
+ ['d:posttest:echo posttest'],
+ ['e:test:exit 0'],
+ ['e:start:echo start something'],
+ ])
+ t.end()
+ })
+ })
+
+ t.test('list no scripts --loglevel=silent', t => {
+ npmlog.level = 'silent'
+ runScript.execWorkspaces([], [], er => {
+ if (er)
+ throw er
+ t.strictSame(output, [])
+ t.end()
+ })
+ })
+
+ t.test('run scripts across all workspaces', t => {
+ runScript.execWorkspaces(['test'], [], er => {
+ if (er)
+ throw er
+
+ t.match(RUN_SCRIPTS, [
+ {
+ path: resolve(npm.localPrefix, 'packages/c'),
+ pkg: { name: 'c', version: '1.0.0' },
+ event: 'test',
+ },
+ {
+ path: resolve(npm.localPrefix, 'packages/c'),
+ pkg: { name: 'c', version: '1.0.0' },
+ event: 'posttest',
+ },
+ {
+ path: resolve(npm.localPrefix, 'packages/d'),
+ pkg: { name: 'd', version: '1.0.0' },
+ event: 'test',
+ },
+ {
+ path: resolve(npm.localPrefix, 'packages/d'),
+ pkg: { name: 'd', version: '1.0.0' },
+ event: 'posttest',
+ },
+ {
+ path: resolve(npm.localPrefix, 'packages/e'),
+ pkg: { name: 'e' },
+ event: 'test',
+ },
+ ])
+ t.end()
+ })
+ })
+
+ t.test('missing scripts in all workspaces', t => {
+ const LOG = []
+ npmlog.error = (err) => {
+ LOG.push(String(err))
+ }
+ runScript.execWorkspaces(['missing-script'], [], er => {
+ t.match(
+ er,
+ /Missing script: missing-script/,
+ 'should throw missing script error'
+ )
+
+ process.exitCode = 0 // clean exit code
+
+ t.match(RUN_SCRIPTS, [])
+ t.strictSame(LOG.map(cleanOutput), [
+ 'Lifecycle script `missing-script` failed with error:',
+ 'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run',
+ ' in workspace: a@1.0.0',
+ ' at location: {CWD}/test/lib/run-script-workspaces/packages/a',
+ 'Lifecycle script `missing-script` failed with error:',
+ 'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run',
+ ' in workspace: b@2.0.0',
+ ' at location: {CWD}/test/lib/run-script-workspaces/packages/b',
+ 'Lifecycle script `missing-script` failed with error:',
+ 'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run',
+ ' in workspace: c@1.0.0',
+ ' at location: {CWD}/test/lib/run-script-workspaces/packages/c',
+ 'Lifecycle script `missing-script` failed with error:',
+ 'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run',
+ ' in workspace: d@1.0.0',
+ ' at location: {CWD}/test/lib/run-script-workspaces/packages/d',
+ 'Lifecycle script `missing-script` failed with error:',
+ 'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run',
+ ' in workspace: e',
+ ' at location: {CWD}/test/lib/run-script-workspaces/packages/e',
+ 'Lifecycle script `missing-script` failed with error:',
+ 'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run',
+ ' in workspace: noscripts@1.0.0',
+ ' at location: {CWD}/test/lib/run-script-workspaces/packages/noscripts',
+ ], 'should log error msgs for each workspace script')
+
+ t.end()
+ })
+ })
+
+ t.test('missing scripts in some workspaces', t => {
+ const LOG = []
+ npmlog.error = (err) => {
+ LOG.push(String(err))
+ }
+ runScript.execWorkspaces(['test'], ['a', 'b', 'c', 'd'], er => {
+ if (er)
+ throw er
+
+ t.match(RUN_SCRIPTS, [])
+ t.strictSame(LOG.map(cleanOutput), [
+ 'Lifecycle script `test` failed with error:',
+ 'Error: Missing script: "test"\n\nTo see a list of scripts, run:\n npm run',
+ ' in workspace: a@1.0.0',
+ ' at location: {CWD}/test/lib/run-script-workspaces/packages/a',
+ 'Lifecycle script `test` failed with error:',
+ 'Error: Missing script: "test"\n\nTo see a list of scripts, run:\n npm run',
+ ' in workspace: b@2.0.0',
+ ' at location: {CWD}/test/lib/run-script-workspaces/packages/b',
+ ], 'should log error msgs for each workspace script')
+ t.end()
+ })
+ })
+
+ t.test('no workspaces when filtering by user args', t => {
+ runScript.execWorkspaces([], ['foo', 'bar'], er => {
+ t.equal(
+ er.message,
+ 'No workspaces found:\n --workspace=foo --workspace=bar',
+ 'should throw error msg'
+ )
+ t.end()
+ })
+ })
+
+ t.test('no workspaces', t => {
+ const _prevPrefix = npm.localPrefix
+ npm.localPrefix = t.testdir({
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.0.0',
+ }),
+ })
+
+ runScript.execWorkspaces([], [], er => {
+ t.match(er, /No workspaces found!/, 'should throw error msg')
+ npm.localPrefix = _prevPrefix
+ t.end()
+ })
+ })
+
+ t.test('single failed workspace run', t => {
+ const RunScript = requireInject('../../lib/run-script.js', {
+ '@npmcli/run-script': () => {
+ throw new Error('err')
+ },
+ npmlog,
+ '../../lib/utils/is-windows-shell.js': false,
+ })
+ const runScript = new RunScript(npm)
+
+ runScript.execWorkspaces(['test'], ['c'], er => {
+ t.ok('should complete running all targets')
+ process.exitCode = 0 // clean up exit code
+ t.end()
+ })
+ })
+
+ t.test('failed workspace run with succeeded runs', t => {
+ const RunScript = requireInject('../../lib/run-script.js', {
+ '@npmcli/run-script': async opts => {
+ if (opts.pkg.name === 'a')
+ throw new Error('ERR')
+
+ RUN_SCRIPTS.push(opts)
+ },
+ npmlog,
+ '../../lib/utils/is-windows-shell.js': false,
+ })
+ const runScript = new RunScript(npm)
+
+ runScript.execWorkspaces(['glorp'], ['a', 'b'], er => {
+ t.match(RUN_SCRIPTS, [
+ {
+ path: resolve(npm.localPrefix, 'packages/b'),
+ pkg: { name: 'b', version: '2.0.0' },
+ event: 'glorp',
+ },
+ ])
+
+ process.exitCode = 0 // clean up exit code
+ t.end()
+ })
+ })
+
+ t.end()
+})
diff --git a/deps/npm/test/lib/search.js b/deps/npm/test/lib/search.js
index b1ba7775c7..b7b4084421 100644
--- a/deps/npm/test/lib/search.js
+++ b/deps/npm/test/lib/search.js
@@ -1,6 +1,7 @@
const Minipass = require('minipass')
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const libnpmsearchResultFixture =
require('../fixtures/libnpmsearch-stream-result.js')
@@ -12,12 +13,17 @@ const flatOptions = {
opts: '',
},
}
-const npm = {
+const config = {
+ json: false,
+ parseable: false,
+}
+const npm = mockNpm({
+ config,
flatOptions: { ...flatOptions },
output: (...msg) => {
result += msg.join('\n')
},
-}
+})
const npmlog = {
silly () {},
clearProgress () {},
@@ -29,12 +35,13 @@ const mocks = {
npmlog,
libnpmsearch,
'../../lib/utils/usage.js': () => 'usage instructions',
- // '../../lib/search/format-package-stream.js': a => a,
}
t.afterEach(cb => {
result = ''
- npm.flatOptions = flatOptions
+ config.json = false
+ config.parseable = false
+ npm.flatOptions = { ...flatOptions }
cb()
})
@@ -86,7 +93,8 @@ t.test('search <name> --json', (t) => {
const src = new Minipass()
src.objectMode = true
- flatOptions.json = true
+ npm.flatOptions.json = true
+ config.json = true
const libnpmsearch = {
stream () {
return src
@@ -114,7 +122,7 @@ t.test('search <name> --json', (t) => {
'should have expected search results as json'
)
- flatOptions.json = false
+ config.json = false
t.end()
})
diff --git a/deps/npm/test/lib/set-script.js b/deps/npm/test/lib/set-script.js
index 7a057c5036..b6b6e2519f 100644
--- a/deps/npm/test/lib/set-script.js
+++ b/deps/npm/test/lib/set-script.js
@@ -31,6 +31,7 @@ test.test('fails when package.json not found', (t) => {
})
test.test('fails on invalid JSON', (t) => {
const SetScript = requireInject('../../lib/set-script.js', {
+ '../../lib/utils/config/definitions.js': {},
fs: {
readFile: () => {}, // read-package-json-fast explodes w/o this
readFileSync: (name, charcode) => {
@@ -45,6 +46,7 @@ test.test('fails on invalid JSON', (t) => {
test.test('creates scripts object', (t) => {
var mockFile = ''
const SetScript = requireInject('../../lib/set-script.js', {
+ '../../lib/utils/config/definitions.js': {},
fs: {
readFileSync: (name, charcode) => {
return '{}'
@@ -70,6 +72,7 @@ test.test('creates scripts object', (t) => {
test.test('warns before overwriting', (t) => {
var warningListened = ''
const SetScript = requireInject('../../lib/set-script.js', {
+ '../../lib/utils/config/definitions.js': {},
fs: {
readFileSync: (name, charcode) => {
return JSON.stringify({
@@ -102,6 +105,7 @@ test.test('warns before overwriting', (t) => {
test.test('provided indentation and eol is used', (t) => {
var mockFile = ''
const SetScript = requireInject('../../lib/set-script.js', {
+ '../../lib/utils/config/definitions.js': {},
fs: {
readFileSync: (name, charcode) => {
return '{}'
@@ -128,6 +132,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', {
+ '../../lib/utils/config/definitions.js': {},
fs: {
readFileSync: (name, charcode) => {
return '{}'
diff --git a/deps/npm/test/lib/shrinkwrap.js b/deps/npm/test/lib/shrinkwrap.js
index dc4bc3b220..faf452ea70 100644
--- a/deps/npm/test/lib/shrinkwrap.js
+++ b/deps/npm/test/lib/shrinkwrap.js
@@ -1,16 +1,21 @@
const t = require('tap')
const fs = require('fs')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
-const npm = {
+const config = {
+ global: false,
+}
+const flatOptions = {
+ depth: 0,
+}
+const npm = mockNpm({
+ config,
+ flatOptions,
lockfileVersion: 2,
globalDir: '',
- flatOptions: {
- depth: 0,
- global: false,
- },
prefix: '',
-}
+})
const tree = {
meta: {
hiddenLockfile: null,
@@ -32,11 +37,12 @@ const mocks = {
}
},
'../../lib/utils/usage.js': () => 'usage instructions',
+ '../../lib/utils/config/definitions.js': {},
}
t.afterEach(cb => {
npm.prefix = ''
- npm.flatOptions.global = false
+ config.global = false
npm.globalDir = ''
cb()
})
@@ -50,7 +56,7 @@ t.test('no args', t => {
constructor (args) {
t.deepEqual(
args,
- { ...npm.flatOptions, path: npm.prefix },
+ { ...flatOptions, path: npm.prefix },
'should call arborist constructor with expected args'
)
}
@@ -101,7 +107,7 @@ t.test('no virtual tree', t => {
constructor (args) {
t.deepEqual(
args,
- { ...npm.flatOptions, path: npm.prefix },
+ { ...flatOptions, path: npm.prefix },
'should call arborist constructor with expected args'
)
}
@@ -156,7 +162,7 @@ t.test('existing package-json file', t => {
constructor (args) {
t.deepEqual(
args,
- { ...npm.flatOptions, path: npm.prefix },
+ { ...flatOptions, path: npm.prefix },
'should call arborist constructor with expected args'
)
}
@@ -218,7 +224,7 @@ t.test('update shrinkwrap file version', t => {
constructor (args) {
t.deepEqual(
args,
- { ...npm.flatOptions, path: npm.prefix },
+ { ...flatOptions, path: npm.prefix },
'should call arborist constructor with expected args'
)
}
@@ -272,7 +278,7 @@ t.test('update to date shrinkwrap file', t => {
constructor (args) {
t.deepEqual(
args,
- { ...npm.flatOptions, path: npm.prefix },
+ { ...flatOptions, path: npm.prefix },
'should call arborist constructor with expected args'
)
}
@@ -320,7 +326,7 @@ t.test('update to date shrinkwrap file', t => {
t.test('shrinkwrap --global', t => {
const Shrinkwrap = requireInject('../../lib/shrinkwrap.js', mocks)
- npm.flatOptions.global = true
+ config.global = true
const shrinkwrap = new Shrinkwrap(npm)
shrinkwrap.exec([], err => {
diff --git a/deps/npm/test/lib/star.js b/deps/npm/test/lib/star.js
index 774fabe392..fa75d21057 100644
--- a/deps/npm/test/lib/star.js
+++ b/deps/npm/test/lib/star.js
@@ -1,16 +1,20 @@
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
const t = require('tap')
let result = ''
const noop = () => null
-const npm = {
- config: { get () {} },
- flatOptions: { unicode: false },
+const config = {
+ unicode: false,
+ 'star.unstar': false,
+}
+const npm = mockNpm({
+ config,
output: (...msg) => {
result += msg.join('\n')
},
-}
+})
const npmFetch = { json: noop }
const npmlog = { error: noop, info: noop, verbose: noop }
const mocks = {
@@ -24,8 +28,8 @@ const Star = requireInject('../../lib/star.js', mocks)
const star = new Star(npm)
t.afterEach(cb => {
- npm.config = { get () {} }
- npm.flatOptions.unicode = false
+ config.unicode = false
+ config['star.unstar'] = false
npmlog.info = noop
result = ''
cb()
@@ -73,7 +77,7 @@ t.test('star a package', t => {
t.test('unstar a package', t => {
t.plan(4)
const pkgName = '@npmcli/arborist'
- npm.config.get = key => key === 'star.unstar'
+ config['star.unstar'] = true
npmFetch.json = async (uri, opts) => ({
_id: pkgName,
_rev: 'hash',
@@ -100,7 +104,7 @@ t.test('unstar a package', t => {
t.test('unicode', async t => {
t.test('star a package', t => {
- npm.flatOptions.unicode = true
+ config.unicode = true
npmFetch.json = async (uri, opts) => ({})
star.exec(['pkg'], err => {
if (err)
@@ -115,8 +119,8 @@ t.test('unicode', async t => {
})
t.test('unstar a package', t => {
- npm.flatOptions.unicode = true
- npm.config.get = key => key === 'star.unstar'
+ config.unicode = true
+ config['star.unstar'] = true
npmFetch.json = async (uri, opts) => ({})
star.exec(['pkg'], err => {
if (err)
diff --git a/deps/npm/test/lib/uninstall.js b/deps/npm/test/lib/uninstall.js
index c62b59950b..5cb8a243ec 100644
--- a/deps/npm/test/lib/uninstall.js
+++ b/deps/npm/test/lib/uninstall.js
@@ -2,18 +2,18 @@ const fs = require('fs')
const { resolve } = require('path')
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
-const npm = {
+const npm = mockNpm({
globalDir: '',
- flatOptions: {
+ config: {
global: false,
prefix: '',
},
localPrefix: '',
-}
+})
const mocks = {
'../../lib/utils/reify-finish.js': () => Promise.resolve(),
- '../../lib/utils/usage.js': () => 'usage instructions',
}
const Uninstall = requireInject('../../lib/uninstall.js', mocks)
@@ -85,13 +85,13 @@ t.test('remove single installed lib', t => {
const b = resolve(path, 'node_modules/b')
t.ok(() => fs.statSync(b))
- npm.flatOptions.prefix = path
+ npm.config.set('prefix', path)
uninstall.exec(['b'], err => {
if (err)
throw err
- t.throws(() => fs.statSync(b), 'should have removed package from nm')
+ t.throws(() => fs.statSync(b), 'should have removed package from npm')
t.end()
})
})
@@ -148,7 +148,7 @@ t.test('remove multiple installed libs', t => {
t.ok(() => fs.statSync(a))
t.ok(() => fs.statSync(b))
- npm.flatOptions.prefix = path
+ npm.config.set('prefix', path)
uninstall.exec(['b'], err => {
if (err)
@@ -195,8 +195,8 @@ t.test('no args global', t => {
npm.localPrefix = resolve(path, 'projects', 'a')
npm.globalDir = resolve(path, 'lib', 'node_modules')
- npm.flatOptions.global = true
- npm.flatOptions.prefix = path
+ npm.config.set('global', true)
+ npm.config.set('prefix', path)
const a = resolve(path, 'lib/node_modules/a')
t.ok(() => fs.statSync(a))
@@ -221,8 +221,7 @@ t.test('no args global but no package.json', t => {
uninstall.exec([], err => {
t.match(
err,
- 'usage instructions',
- 'should throw usage instructions'
+ 'npm uninstall'
)
t.end()
diff --git a/deps/npm/test/lib/unpublish.js b/deps/npm/test/lib/unpublish.js
index b1255b94a8..ba99b53303 100644
--- a/deps/npm/test/lib/unpublish.js
+++ b/deps/npm/test/lib/unpublish.js
@@ -1,19 +1,21 @@
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
let result = ''
const noop = () => null
-const npm = {
+const config = {
+ force: false,
+ silent: false,
+ loglevel: 'silly',
+}
+const npm = mockNpm({
localPrefix: '',
- flatOptions: {
- force: false,
- silent: false,
- loglevel: 'silly',
- },
+ config,
output: (...msg) => {
result += msg.join('\n')
},
-}
+})
const mocks = {
npmlog: { silly () {}, verbose () {} },
libnpmaccess: { lsPackages: noop },
@@ -28,16 +30,16 @@ const mocks = {
t.afterEach(cb => {
result = ''
- npm.flatOptions.force = false
- npm.flatOptions.loglevel = 'silly'
- npm.flatOptions.silent = false
+ config.force = false
+ config.loglevel = 'silly'
+ config.silent = false
cb()
})
t.test('no args --force', t => {
t.plan(9)
- npm.flatOptions.force = true
+ config.force = true
const npmlog = {
silly (title) {
@@ -67,9 +69,6 @@ t.test('no args --force', t => {
t.deepEqual(
opts,
{
- force: true,
- silent: false,
- loglevel: 'silly',
publishConfig: undefined,
},
'should unpublish with expected opts'
@@ -102,7 +101,7 @@ t.test('no args --force', t => {
})
t.test('no args --force missing package.json', t => {
- npm.flatOptions.force = true
+ config.force = true
const Unpublish = requireInject('../../lib/unpublish.js', {
...mocks,
@@ -124,7 +123,7 @@ t.test('no args --force missing package.json', t => {
})
t.test('no args --force unknown error reading package.json', t => {
- npm.flatOptions.force = true
+ config.force = true
const Unpublish = requireInject('../../lib/unpublish.js', {
...mocks,
@@ -200,11 +199,7 @@ t.test('unpublish <pkg>@version', t => {
t.equal(spec, pa, 'should unpublish expected parsed spec')
t.deepEqual(
opts,
- {
- force: false,
- silent: false,
- loglevel: 'silly',
- },
+ {},
'should unpublish with expected opts'
)
},
@@ -231,7 +226,7 @@ t.test('unpublish <pkg>@version', t => {
})
t.test('no version found in package.json', t => {
- npm.flatOptions.force = true
+ config.force = true
const npa = () => ({
name: 'pkg',
@@ -263,7 +258,7 @@ t.test('no version found in package.json', t => {
})
t.test('unpublish <pkg> --force no version set', t => {
- npm.flatOptions.force = true
+ config.force = true
const Unpublish = requireInject('../../lib/unpublish.js', {
...mocks,
@@ -289,7 +284,7 @@ t.test('unpublish <pkg> --force no version set', t => {
})
t.test('silent', t => {
- npm.flatOptions.loglevel = 'silent'
+ config.loglevel = 'silent'
const npa = () => ({
name: 'pkg',
diff --git a/deps/npm/test/lib/update.js b/deps/npm/test/lib/update.js
index 15195573f5..695218a7f6 100644
--- a/deps/npm/test/lib/update.js
+++ b/deps/npm/test/lib/update.js
@@ -1,16 +1,18 @@
const { resolve } = require('path')
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
+const config = {
+ depth: 0,
+ global: false,
+}
const noop = () => null
-const npm = {
+const npm = mockNpm({
globalDir: '',
- flatOptions: {
- depth: 0,
- global: false,
- },
+ config,
prefix: '',
-}
+})
const mocks = {
npmlog: { warn () {} },
'@npmcli/arborist': class {
@@ -22,7 +24,7 @@ const mocks = {
t.afterEach(cb => {
npm.prefix = ''
- npm.flatOptions.global = false
+ config.global = false
npm.globalDir = ''
cb()
})
@@ -99,7 +101,7 @@ t.test('update --depth=<number>', t => {
t.plan(2)
npm.prefix = '/project/a'
- npm.flatOptions.depth = 1
+ config.depth = 1
const Update = requireInject('../../lib/update.js', {
...mocks,
@@ -131,7 +133,7 @@ t.test('update --global', t => {
npm.prefix = '/project/a'
npm.globalDir = resolve(process.cwd(), 'global/lib/node_modules')
- npm.flatOptions.global = true
+ config.global = true
class Arborist {
constructor (args) {
diff --git a/deps/npm/test/lib/utils/config.js b/deps/npm/test/lib/utils/config.js
deleted file mode 100644
index 4d4b1a1d1a..0000000000
--- a/deps/npm/test/lib/utils/config.js
+++ /dev/null
@@ -1,143 +0,0 @@
-const t = require('tap')
-const requireInject = require('require-inject')
-
-// have to fake the node version, or else it'll only pass on this one
-Object.defineProperty(process, 'version', {
- value: 'v14.8.0',
-})
-
-t.formatSnapshot = obj => {
- if (typeof obj !== 'object' || !obj || !obj.types)
- return obj
-
- return {
- ...obj,
- defaults: {
- ...obj.defaults,
- cache: '{CACHE DIR} ' + path.basename(obj.defaults.cache),
- },
- types: formatTypes(obj.types),
- }
-}
-
-const path = require('path')
-const url = require('url')
-const semver = require('semver')
-
-const formatTypes = (types) => Object.entries(types).map(([key, value]) => {
- return [key, formatTypeValue(value)]
-}).reduce((set, [key, value]) => {
- set[key] = value
- return set
-}, {})
-
-const formatTypeValue = (value) => {
- if (Array.isArray(value))
- return value.map(formatTypeValue)
- else if (value === url)
- return '{URL MODULE}'
- else if (value === path)
- return '{PATH MODULE}'
- else if (value === semver)
- return '{SEMVER MODULE}'
- else if (typeof value === 'function')
- return `{${value.name} TYPE}`
- else
- return value
-}
-
-process.env.ComSpec = 'cmd.exe'
-process.env.SHELL = '/usr/local/bin/bash'
-process.env.LANG = 'UTF-8'
-delete process.env.LC_ALL
-delete process.env.LC_CTYPE
-process.env.EDITOR = 'vim'
-process.env.VISUAL = 'mate'
-
-const networkInterfacesThrow = () => {
- throw new Error('no network interfaces for some reason')
-}
-const networkInterfaces = () => ({
- eth420: [{ address: '127.0.0.1' }],
- eth69: [{ address: 'no place like home' }],
-})
-const tmpdir = () => '/tmp'
-const os = { networkInterfaces, tmpdir }
-const pkg = { version: '7.0.0' }
-
-t.test('working network interfaces, not windows', t => {
- const config = requireInject('../../../lib/utils/config.js', {
- os,
- '@npmcli/ci-detect': () => false,
- '../../../lib/utils/is-windows.js': false,
- '../../../package.json': pkg,
- })
- t.matchSnapshot(config)
- t.end()
-})
-
-t.test('no working network interfaces, on windows', t => {
- const config = requireInject('../../../lib/utils/config.js', {
- os: { tmpdir, networkInterfaces: networkInterfacesThrow },
- '@npmcli/ci-detect': () => false,
- '../../../lib/utils/is-windows.js': true,
- '../../../package.json': pkg,
- })
- t.matchSnapshot(config)
- t.end()
-})
-
-t.test('no comspec on windows', t => {
- delete process.env.ComSpec
- const config = requireInject('../../../lib/utils/config.js', {
- os: { tmpdir, networkInterfaces: networkInterfacesThrow },
- '@npmcli/ci-detect': () => false,
- '../../../lib/utils/is-windows.js': true,
- })
- t.equal(config.defaults.shell, 'cmd')
- t.end()
-})
-
-t.test('no shell on posix', t => {
- delete process.env.SHELL
- const config = requireInject('../../../lib/utils/config.js', {
- os,
- '@npmcli/ci-detect': () => false,
- '../../../lib/utils/is-windows.js': false,
- })
- t.equal(config.defaults.shell, 'sh')
- t.end()
-})
-
-t.test('no EDITOR env, use VISUAL', t => {
- delete process.env.EDITOR
- const config = requireInject('../../../lib/utils/config.js', {
- os,
- '@npmcli/ci-detect': () => false,
- '../../../lib/utils/is-windows.js': false,
- })
- t.equal(config.defaults.editor, 'mate')
- t.end()
-})
-
-t.test('no VISUAL, use system default, not windows', t => {
- delete process.env.VISUAL
- const config = requireInject('../../../lib/utils/config.js', {
- os,
- '@npmcli/ci-detect': () => false,
- '../../../lib/utils/is-windows.js': false,
- })
- t.equal(config.defaults.editor, 'vi')
- t.end()
-})
-
-t.test('no VISUAL, use system default, not windows', t => {
- delete process.env.VISUAL
- const config = requireInject('../../../lib/utils/config.js', {
- os,
- '@npmcli/ci-detect': () => false,
- '../../../lib/utils/is-windows.js': true,
- })
- t.equal(config.defaults.editor, 'notepad.exe')
- t.end()
-})
diff --git a/deps/npm/test/lib/utils/config/definition.js b/deps/npm/test/lib/utils/config/definition.js
new file mode 100644
index 0000000000..56e10da0cb
--- /dev/null
+++ b/deps/npm/test/lib/utils/config/definition.js
@@ -0,0 +1,185 @@
+const t = require('tap')
+const Definition = require('../../../../lib/utils/config/definition.js')
+const {
+ typeDefs: {
+ semver: { type: semver },
+ Umask: { type: Umask },
+ url: { type: url },
+ path: { type: path },
+ },
+} = require('@npmcli/config')
+
+t.test('basic definition', async t => {
+ const def = new Definition('key', {
+ default: 'some default value',
+ type: [Number, String],
+ description: 'just a test thingie',
+ })
+ t.same(def, {
+ constructor: Definition,
+ key: 'key',
+ default: 'some default value',
+ defaultDescription: '"some default value"',
+ type: [Number, String],
+ hint: '<key>',
+ usage: '--key <key>|--key <key>',
+ typeDescription: 'Number or String',
+ description: 'just a test thingie',
+ })
+ t.matchSnapshot(def.describe(), 'human-readable description')
+
+ const deprecated = new Definition('deprecated', {
+ deprecated: 'do not use this',
+ default: 1234,
+ description: ' it should not be used\n ever\n\n not even once.\n\n',
+ type: Number,
+ defaultDescription: 'A number bigger than 1',
+ typeDescription: 'An expression of a numeric quantity using numerals',
+ })
+ t.matchSnapshot(deprecated.describe(), 'description of deprecated thing')
+
+ const nullOrUmask = new Definition('key', {
+ default: null,
+ type: [null, Umask],
+ description: 'asdf',
+ })
+ t.equal(nullOrUmask.typeDescription, 'null or Octal numeric string in range 0000..0777 (0..511)')
+ const nullDateOrBool = new Definition('key', {
+ default: 7,
+ type: [null, Date, Boolean],
+ description: 'asdf',
+ })
+ t.equal(nullDateOrBool.typeDescription, 'null, Date, or Boolean')
+ const manyPaths = new Definition('key', {
+ default: ['asdf'],
+ type: [path, Array],
+ description: 'asdf',
+ })
+ t.equal(manyPaths.typeDescription, 'Path (can be set multiple times)')
+ const pathOrUrl = new Definition('key', {
+ default: ['https://example.com'],
+ type: [path, url],
+ description: 'asdf',
+ })
+ t.equal(pathOrUrl.typeDescription, 'Path or URL')
+ const multi12 = new Definition('key', {
+ default: [],
+ type: [1, 2, Array],
+ description: 'asdf',
+ })
+ t.equal(multi12.typeDescription, '1 or 2 (can be set multiple times)')
+ const multi123 = new Definition('key', {
+ default: [],
+ type: [1, 2, 3, Array],
+ description: 'asdf',
+ })
+ t.equal(multi123.typeDescription, '1, 2, or 3 (can be set multiple times)')
+ const multi123Semver = new Definition('key', {
+ default: [],
+ type: [1, 2, 3, Array, semver],
+ description: 'asdf',
+ })
+ t.equal(multi123Semver.typeDescription, '1, 2, 3, or SemVer string (can be set multiple times)')
+ const hasUsage = new Definition('key', {
+ default: 'test default',
+ type: String,
+ description: 'test description',
+ usage: 'test usage',
+ })
+ t.equal(hasUsage.usage, 'test usage')
+ const hasShort = new Definition('key', {
+ default: 'test default',
+ short: 't',
+ type: String,
+ description: 'test description',
+ })
+ t.equal(hasShort.usage, '-t|--key <key>')
+ const hardCodedTypes = new Definition('key', {
+ default: 'test default',
+ type: ['string1', 'string2'],
+ description: 'test description',
+ })
+ t.equal(hardCodedTypes.usage, '--key <string1|string2>')
+ const hardCodedOptionalTypes = new Definition('key', {
+ default: 'test default',
+ type: [null, 'string1', 'string2'],
+ description: 'test description',
+ })
+ t.equal(hardCodedOptionalTypes.usage, '--key <string1|string2>')
+ const hasHint = new Definition('key', {
+ default: 'test default',
+ type: String,
+ description: 'test description',
+ hint: '<testparam>',
+ })
+ t.equal(hasHint.usage, '--key <testparam>')
+})
+
+t.test('missing fields', async t => {
+ t.throws(() => new Definition('lacks-default', {
+ description: 'no default',
+ type: String,
+ }), { message: 'config lacks default: lacks-default' })
+ t.throws(() => new Definition('lacks-type', {
+ description: 'no type',
+ default: 1234,
+ }), { message: 'config lacks type: lacks-type' })
+ t.throws(() => new Definition(null, {
+ description: 'falsey key',
+ default: 1234,
+ type: Number,
+ }), { message: 'config lacks key: null' })
+ t.throws(() => new Definition('extra-field', {
+ type: String,
+ default: 'extra',
+ extra: 'more than is wanted',
+ description: 'this is not ok',
+ }), { message: 'config defines unknown field extra: extra-field' })
+})
+
+t.test('long description', async t => {
+ const { stdout: { columns } } = process
+ t.teardown(() => process.stdout.columns = columns)
+
+ const long = new Definition('walden', {
+ description: `
+ WHEN I WROTE the following pages, or rather the bulk of them, I lived
+ alone, in the woods, a mile from any neighbor, in a house which I had
+ built myself, on the shore of Walden Pond, in Concord, Massachusetts, and
+ earned my living by the labor of my hands only. I lived there two years
+ and two months. At present I am a sojourner in civilized life again.
+
+ I should not obtrude my affairs so much on the notice of my readers if
+ very particular inquiries had not been made by my townsmen concerning my
+ mode of life, which some would call impertinent, though they do not
+ appear to me at all impertinent, but, considering the circumstances, very
+ natural and pertinent.
+
+ \`\`\`
+ this.is('a', {
+ code: 'sample',
+ })
+
+ with (multiple) {
+ blocks()
+ }
+ \`\`\`
+ `,
+ default: true,
+ type: Boolean,
+ })
+ process.stdout.columns = 40
+ t.matchSnapshot(long.describe(), 'cols=40')
+
+ process.stdout.columns = 9000
+ t.matchSnapshot(long.describe(), 'cols=9000')
+
+ process.stdout.columns = 0
+ t.matchSnapshot(long.describe(), 'cols=0')
+
+ process.stdout.columns = -1
+ t.matchSnapshot(long.describe(), 'cols=-1')
+
+ process.stdout.columns = NaN
+ t.matchSnapshot(long.describe(), 'cols=NaN')
+})
diff --git a/deps/npm/test/lib/utils/config/definitions.js b/deps/npm/test/lib/utils/config/definitions.js
new file mode 100644
index 0000000000..3169feefb8
--- /dev/null
+++ b/deps/npm/test/lib/utils/config/definitions.js
@@ -0,0 +1,697 @@
+const t = require('tap')
+
+const requireInject = require('require-inject')
+const { resolve } = require('path')
+
+// have to fake the node version, or else it'll only pass on this one
+Object.defineProperty(process, 'version', {
+ value: 'v14.8.0',
+})
+
+// also fake the npm version, so that it doesn't get reset every time
+const pkg = require('../../../../package.json')
+
+// this is a pain to keep typing
+const defpath = '../../../../lib/utils/config/definitions.js'
+
+// set this in the test when we need it
+delete process.env.NODE_ENV
+const definitions = require(defpath)
+
+const isWin = '../../../../lib/utils/is-windows.js'
+
+// snapshot these just so we note when they change
+t.matchSnapshot(Object.keys(definitions), 'all config keys')
+t.matchSnapshot(Object.keys(definitions).filter(d => d.flatten),
+ 'all config keys that are shared to flatOptions')
+
+t.equal(definitions['npm-version'].default, pkg.version, 'npm-version default')
+t.equal(definitions['node-version'].default, process.version, 'node-version default')
+
+t.test('basic flattening function camelCases from css-case', t => {
+ const flat = {}
+ const obj = { 'always-auth': true }
+ definitions['always-auth'].flatten('always-auth', obj, flat)
+ t.strictSame(flat, { alwaysAuth: true })
+ t.end()
+})
+
+t.test('editor', t => {
+ t.test('has EDITOR and VISUAL, use EDITOR', t => {
+ process.env.EDITOR = 'vim'
+ process.env.VISUAL = 'mate'
+ const defs = requireInject(defpath)
+ t.equal(defs.editor.default, 'vim')
+ t.end()
+ })
+ t.test('has VISUAL but no EDITOR, use VISUAL', t => {
+ delete process.env.EDITOR
+ process.env.VISUAL = 'mate'
+ const defs = requireInject(defpath)
+ t.equal(defs.editor.default, 'mate')
+ t.end()
+ })
+ t.test('has neither EDITOR nor VISUAL, system specific', t => {
+ delete process.env.EDITOR
+ delete process.env.VISUAL
+ const defsWin = requireInject(defpath, {
+ [isWin]: true,
+ })
+ t.equal(defsWin.editor.default, 'notepad.exe')
+ const defsNix = requireInject(defpath, {
+ [isWin]: false,
+ })
+ t.equal(defsNix.editor.default, 'vi')
+ t.end()
+ })
+ t.end()
+})
+
+t.test('shell', t => {
+ t.test('windows, env.ComSpec then cmd.exe', t => {
+ process.env.ComSpec = 'command.com'
+ const defsComSpec = requireInject(defpath, {
+ [isWin]: true,
+ })
+ t.equal(defsComSpec.shell.default, 'command.com')
+ delete process.env.ComSpec
+ const defsNoComSpec = requireInject(defpath, {
+ [isWin]: true,
+ })
+ t.equal(defsNoComSpec.shell.default, 'cmd')
+ t.end()
+ })
+
+ t.test('nix, SHELL then sh', t => {
+ process.env.SHELL = '/usr/local/bin/bash'
+ const defsShell = requireInject(defpath, {
+ [isWin]: false,
+ })
+ t.equal(defsShell.shell.default, '/usr/local/bin/bash')
+ delete process.env.SHELL
+ const defsNoShell = requireInject(defpath, {
+ [isWin]: false,
+ })
+ t.equal(defsNoShell.shell.default, 'sh')
+ t.end()
+ })
+
+ t.end()
+})
+
+t.test('local-address allowed types', t => {
+ t.test('get list from os.networkInterfaces', t => {
+ const os = {
+ tmpdir: () => '/tmp',
+ networkInterfaces: () => ({
+ eth420: [{ address: '127.0.0.1' }],
+ eth69: [{ address: 'no place like home' }],
+ }),
+ }
+ const defs = requireInject(defpath, { os })
+ t.same(defs['local-address'].type, [
+ null,
+ '127.0.0.1',
+ 'no place like home',
+ ])
+ t.end()
+ })
+ t.test('handle os.networkInterfaces throwing', t => {
+ const os = {
+ tmpdir: () => '/tmp',
+ networkInterfaces: () => {
+ throw new Error('no network interfaces for some reason')
+ },
+ }
+ const defs = requireInject(defpath, { os })
+ t.same(defs['local-address'].type, [null])
+ t.end()
+ })
+ t.end()
+})
+
+t.test('unicode allowed?', t => {
+ const { LC_ALL, LC_CTYPE, LANG } = process.env
+ t.teardown(() => Object.assign(process.env, { LC_ALL, LC_CTYPE, LANG }))
+
+ process.env.LC_ALL = 'utf8'
+ process.env.LC_CTYPE = 'UTF-8'
+ process.env.LANG = 'Unicode utf-8'
+
+ const lcAll = requireInject(defpath)
+ t.equal(lcAll.unicode.default, true)
+ process.env.LC_ALL = 'no unicode for youUUUU!'
+ const noLcAll = requireInject(defpath)
+ t.equal(noLcAll.unicode.default, false)
+
+ delete process.env.LC_ALL
+ const lcCtype = requireInject(defpath)
+ t.equal(lcCtype.unicode.default, true)
+ process.env.LC_CTYPE = 'something other than unicode version 8'
+ const noLcCtype = requireInject(defpath)
+ t.equal(noLcCtype.unicode.default, false)
+
+ delete process.env.LC_CTYPE
+ const lang = requireInject(defpath)
+ t.equal(lang.unicode.default, true)
+ process.env.LANG = 'ISO-8859-1'
+ const noLang = requireInject(defpath)
+ t.equal(noLang.unicode.default, false)
+ t.end()
+})
+
+t.test('cache', t => {
+ process.env.LOCALAPPDATA = 'app/data/local'
+ const defsWinLocalAppData = requireInject(defpath, {
+ [isWin]: true,
+ })
+ t.equal(defsWinLocalAppData.cache.default, 'app/data/local/npm-cache')
+
+ delete process.env.LOCALAPPDATA
+ const defsWinNoLocalAppData = requireInject(defpath, {
+ [isWin]: true,
+ })
+ t.equal(defsWinNoLocalAppData.cache.default, '~/npm-cache')
+
+ const defsNix = requireInject(defpath, {
+ [isWin]: false,
+ })
+ t.equal(defsNix.cache.default, '~/.npm')
+
+ const flat = {}
+ defsNix.cache.flatten('cache', { cache: '/some/cache/value' }, flat)
+ const {join} = require('path')
+ t.equal(flat.cache, join('/some/cache/value', '_cacache'))
+
+ t.end()
+})
+
+t.test('flatteners that populate flat.omit array', t => {
+ t.test('also', t => {
+ const flat = {}
+ const obj = {}
+
+ // ignored if setting is not dev or development
+ obj.also = 'ignored'
+ definitions.also.flatten('also', obj, flat)
+ t.strictSame(obj, {also: 'ignored'}, 'nothing done')
+ t.strictSame(flat, {}, 'nothing done')
+
+ obj.also = 'development'
+ definitions.also.flatten('also', obj, flat)
+ t.strictSame(obj, { also: 'development', include: ['dev'] }, 'marked dev as included')
+ t.strictSame(flat, { omit: [] }, 'nothing omitted, so nothing changed')
+
+ obj.omit = ['dev', 'optional']
+ obj.include = []
+ definitions.also.flatten('also', obj, flat)
+ t.strictSame(obj, { also: 'development', omit: ['dev', 'optional'], include: ['dev'] }, 'marked dev as included')
+ t.strictSame(flat, { omit: ['optional'] }, 'removed dev from omit')
+ t.end()
+ })
+
+ t.test('include', t => {
+ const flat = {}
+ const obj = { include: ['dev'] }
+ definitions.include.flatten('include', obj, flat)
+ t.strictSame(flat, {omit: []}, 'not omitting anything')
+ obj.omit = ['optional', 'dev']
+ definitions.include.flatten('include', obj, flat)
+ t.strictSame(flat, {omit: ['optional']}, 'only omitting optional')
+ t.end()
+ })
+
+ t.test('omit', t => {
+ const flat = {}
+ const obj = { include: ['dev'], omit: ['dev', 'optional'] }
+ definitions.omit.flatten('omit', obj, flat)
+ t.strictSame(flat, { omit: ['optional'] }, 'do not omit what is included')
+
+ process.env.NODE_ENV = 'production'
+ const defProdEnv = requireInject(defpath)
+ t.strictSame(defProdEnv.omit.default, ['dev'], 'omit dev in production')
+ t.end()
+ })
+
+ t.test('only', t => {
+ const flat = {}
+ const obj = { only: 'asdf' }
+ definitions.only.flatten('only', obj, flat)
+ t.strictSame(flat, {}, 'ignored if value is not production')
+
+ obj.only = 'prod'
+ definitions.only.flatten('only', obj, flat)
+ t.strictSame(flat, {omit: ['dev']}, 'omit dev when --only=prod')
+
+ obj.include = ['dev']
+ flat.omit = []
+ definitions.only.flatten('only', obj, flat)
+ t.strictSame(flat, {omit: []}, 'do not omit when included')
+
+ t.end()
+ })
+
+ t.test('optional', t => {
+ const flat = {}
+ const obj = { optional: null }
+
+ definitions.optional.flatten('optional', obj, flat)
+ t.strictSame(obj, { optional: null }, 'do nothing by default')
+ t.strictSame(flat, {}, 'do nothing by default')
+
+ obj.optional = true
+ definitions.optional.flatten('optional', obj, flat)
+ t.strictSame(obj, {include: ['optional'], optional: true}, 'include optional when set')
+ t.strictSame(flat, {omit: []}, 'nothing to omit in flatOptions')
+
+ delete obj.include
+ obj.optional = false
+ definitions.optional.flatten('optional', obj, flat)
+ t.strictSame(obj, {omit: ['optional'], optional: false}, 'omit optional when set false')
+ t.strictSame(flat, {omit: ['optional']}, 'omit optional when set false')
+
+ t.end()
+ })
+
+ t.test('production', t => {
+ const flat = {}
+ const obj = {production: true}
+ definitions.production.flatten('production', obj, flat)
+ t.strictSame(obj, {production: true, omit: ['dev']}, '--production sets --omit=dev')
+ t.strictSame(flat, {omit: ['dev']}, '--production sets --omit=dev')
+
+ delete obj.omit
+ obj.production = false
+ delete flat.omit
+ definitions.production.flatten('production', obj, flat)
+ t.strictSame(obj, {production: false}, '--no-production has no effect')
+ t.strictSame(flat, {}, '--no-production has no effect')
+
+ obj.production = true
+ obj.include = ['dev']
+ definitions.production.flatten('production', obj, flat)
+ t.strictSame(obj, {production: true, include: ['dev'], omit: ['dev']}, 'omit and include dev')
+ t.strictSame(flat, {omit: []}, 'do not omit dev when included')
+
+ t.end()
+ })
+
+ t.end()
+})
+
+t.test('cache-max', t => {
+ const flat = {}
+ const obj = { 'cache-max': 10342 }
+ definitions['cache-max'].flatten('cache-max', obj, flat)
+ t.strictSame(flat, {}, 'no effect if not <= 0')
+ obj['cache-max'] = 0
+ definitions['cache-max'].flatten('cache-max', obj, flat)
+ t.strictSame(flat, {preferOnline: true}, 'preferOnline if <= 0')
+ t.end()
+})
+
+t.test('cache-min', t => {
+ const flat = {}
+ const obj = { 'cache-min': 123 }
+ definitions['cache-min'].flatten('cache-min', obj, flat)
+ t.strictSame(flat, {}, 'no effect if not >= 9999')
+ obj['cache-min'] = 9999
+ definitions['cache-min'].flatten('cache-min', obj, flat)
+ t.strictSame(flat, {preferOffline: true}, 'preferOffline if >=9999')
+ t.end()
+})
+
+t.test('color', t => {
+ const { isTTY } = process.stdout
+ t.teardown(() => process.stdout.isTTY = isTTY)
+
+ const flat = {}
+ const obj = { color: 'always' }
+
+ definitions.color.flatten('color', obj, flat)
+ t.strictSame(flat, {color: true}, 'true when --color=always')
+
+ obj.color = false
+ definitions.color.flatten('color', obj, flat)
+ t.strictSame(flat, {color: false}, 'true when --no-color')
+
+ process.stdout.isTTY = false
+ obj.color = true
+ definitions.color.flatten('color', obj, flat)
+ t.strictSame(flat, {color: false}, 'no color when stdout not tty')
+ process.stdout.isTTY = true
+ definitions.color.flatten('color', obj, flat)
+ t.strictSame(flat, {color: true}, '--color turns on color when stdout is tty')
+
+ delete process.env.NO_COLOR
+ const defsAllowColor = requireInject(defpath)
+ t.equal(defsAllowColor.color.default, true, 'default true when no NO_COLOR env')
+
+ process.env.NO_COLOR = '0'
+ const defsNoColor0 = requireInject(defpath)
+ t.equal(defsNoColor0.color.default, true, 'default true when no NO_COLOR=0')
+
+ process.env.NO_COLOR = '1'
+ const defsNoColor1 = requireInject(defpath)
+ t.equal(defsNoColor1.color.default, false, 'default false when no NO_COLOR=1')
+
+ t.end()
+})
+
+t.test('retry options', t => {
+ const obj = {}
+ // <config>: flat.retry[<option>]
+ const mapping = {
+ 'fetch-retries': 'retries',
+ 'fetch-retry-factor': 'factor',
+ 'fetch-retry-maxtimeout': 'maxTimeout',
+ 'fetch-retry-mintimeout': 'minTimeout',
+ }
+ for (const [config, option] of Object.entries(mapping)) {
+ const msg = `${config} -> retry.${option}`
+ const flat = {}
+ obj[config] = 99
+ definitions[config].flatten(config, obj, flat)
+ t.strictSame(flat, {retry: {[option]: 99}}, msg)
+ delete obj[config]
+ }
+ t.end()
+})
+
+t.test('search options', t => {
+ const obj = {}
+ // <config>: flat.search[<option>]
+ const mapping = {
+ description: 'description',
+ searchexclude: 'exclude',
+ searchlimit: 'limit',
+ searchstaleness: 'staleness',
+ }
+
+ for (const [config, option] of Object.entries(mapping)) {
+ const msg = `${config} -> search.${option}`
+ const flat = {}
+ obj[config] = 99
+ definitions[config].flatten(config, obj, flat)
+ t.strictSame(flat, { search: { limit: 20, [option]: 99 }}, msg)
+ delete obj[config]
+ }
+
+ const flat = {}
+ obj.searchopts = 'a=b&b=c'
+ definitions.searchopts.flatten('searchopts', obj, flat)
+ t.strictSame(flat, {
+ search: {
+ limit: 20,
+ opts: Object.assign(Object.create(null), {
+ a: 'b',
+ b: 'c',
+ }),
+ },
+ }, 'searchopts -> querystring.parse() -> search.opts')
+ delete obj.searchopts
+
+ t.end()
+})
+
+t.test('noProxy', t => {
+ const obj = { noproxy: ['1.2.3.4,2.3.4.5', '3.4.5.6'] }
+ const flat = {}
+ definitions.noproxy.flatten('noproxy', obj, flat)
+ t.strictSame(flat, { noProxy: '1.2.3.4,2.3.4.5,3.4.5.6' })
+ t.end()
+})
+
+t.test('maxSockets', t => {
+ const obj = { maxsockets: 123 }
+ const flat = {}
+ definitions.maxsockets.flatten('maxsockets', obj, flat)
+ t.strictSame(flat, { maxSockets: 123 })
+ t.end()
+})
+
+t.test('projectScope', t => {
+ const obj = { scope: 'asdf' }
+ const flat = {}
+ definitions.scope.flatten('scope', obj, flat)
+ t.strictSame(flat, { projectScope: '@asdf' }, 'prepend @ if needed')
+
+ obj.scope = '@asdf'
+ definitions.scope.flatten('scope', obj, flat)
+ t.strictSame(flat, { projectScope: '@asdf' }, 'leave untouched if has @')
+
+ t.end()
+})
+
+t.test('strictSSL', t => {
+ const obj = { 'strict-ssl': false }
+ const flat = {}
+ definitions['strict-ssl'].flatten('strict-ssl', obj, flat)
+ t.strictSame(flat, { strictSSL: false })
+ obj['strict-ssl'] = true
+ definitions['strict-ssl'].flatten('strict-ssl', obj, flat)
+ t.strictSame(flat, { strictSSL: true })
+ t.end()
+})
+
+t.test('shrinkwrap/package-lock', t => {
+ const obj = { shrinkwrap: false }
+ const flat = {}
+ definitions.shrinkwrap.flatten('shrinkwrap', obj, flat)
+ t.strictSame(flat, {packageLock: false})
+ obj.shrinkwrap = true
+ definitions.shrinkwrap.flatten('shrinkwrap', obj, flat)
+ t.strictSame(flat, {packageLock: true})
+
+ delete obj.shrinkwrap
+ obj['package-lock'] = false
+ definitions['package-lock'].flatten('package-lock', obj, flat)
+ t.strictSame(flat, {packageLock: false})
+ obj['package-lock'] = true
+ definitions['package-lock'].flatten('package-lock', obj, flat)
+ t.strictSame(flat, {packageLock: true})
+
+ t.end()
+})
+
+t.test('scriptShell', t => {
+ const obj = { 'script-shell': null }
+ const flat = {}
+ definitions['script-shell'].flatten('script-shell', obj, flat)
+ t.ok(Object.prototype.hasOwnProperty.call(flat, 'scriptShell'),
+ 'should set it to undefined explicitly')
+ t.strictSame(flat, { scriptShell: undefined }, 'no other fields')
+
+ obj['script-shell'] = 'asdf'
+ definitions['script-shell'].flatten('script-shell', obj, flat)
+ t.strictSame(flat, { scriptShell: 'asdf' }, 'sets if not falsey')
+
+ t.end()
+})
+
+t.test('defaultTag', t => {
+ const obj = { tag: 'next' }
+ const flat = {}
+ definitions.tag.flatten('tag', obj, flat)
+ t.strictSame(flat, {defaultTag: 'next'})
+ t.end()
+})
+
+t.test('timeout', t => {
+ const obj = { 'fetch-timeout': 123 }
+ const flat = {}
+ definitions['fetch-timeout'].flatten('fetch-timeout', obj, flat)
+ t.strictSame(flat, {timeout: 123})
+ t.end()
+})
+
+t.test('saveType', t => {
+ t.test('save-prod', t => {
+ const obj = { 'save-prod': false }
+ const flat = {}
+ definitions['save-prod'].flatten('save-prod', obj, flat)
+ t.strictSame(flat, {}, 'no effect if false and missing')
+ flat.saveType = 'prod'
+ definitions['save-prod'].flatten('save-prod', obj, flat)
+ t.strictSame(flat, {}, 'remove if false and set to prod')
+ flat.saveType = 'dev'
+ definitions['save-prod'].flatten('save-prod', obj, flat)
+ t.strictSame(flat, {saveType: 'dev'}, 'ignore if false and not already prod')
+ obj['save-prod'] = true
+ definitions['save-prod'].flatten('save-prod', obj, flat)
+ t.strictSame(flat, {saveType: 'prod'}, 'set to prod if true')
+ t.end()
+ })
+
+ t.test('save-dev', t => {
+ const obj = { 'save-dev': false }
+ const flat = {}
+ definitions['save-dev'].flatten('save-dev', obj, flat)
+ t.strictSame(flat, {}, 'no effect if false and missing')
+ flat.saveType = 'dev'
+ definitions['save-dev'].flatten('save-dev', obj, flat)
+ t.strictSame(flat, {}, 'remove if false and set to dev')
+ flat.saveType = 'prod'
+ obj['save-dev'] = false
+ definitions['save-dev'].flatten('save-dev', obj, flat)
+ t.strictSame(flat, {saveType: 'prod'}, 'ignore if false and not already dev')
+ obj['save-dev'] = true
+ definitions['save-dev'].flatten('save-dev', obj, flat)
+ t.strictSame(flat, {saveType: 'dev'}, 'set to dev if true')
+ t.end()
+ })
+
+ t.test('save-bundle', t => {
+ const obj = { 'save-bundle': true }
+ const flat = {}
+ definitions['save-bundle'].flatten('save-bundle', obj, flat)
+ t.strictSame(flat, {saveBundle: true}, 'set the saveBundle flag')
+
+ obj['save-bundle'] = false
+ definitions['save-bundle'].flatten('save-bundle', obj, flat)
+ t.strictSame(flat, {saveBundle: false}, 'unset the saveBundle flag')
+
+ obj['save-bundle'] = true
+ obj['save-peer'] = true
+ definitions['save-bundle'].flatten('save-bundle', obj, flat)
+ t.strictSame(flat, {saveBundle: false}, 'false if save-peer is set')
+
+ t.end()
+ })
+
+ t.test('save-peer', t => {
+ const obj = { 'save-peer': false}
+ const flat = {}
+ definitions['save-peer'].flatten('save-peer', obj, flat)
+ t.strictSame(flat, {}, 'no effect if false and not yet set')
+
+ obj['save-peer'] = true
+ definitions['save-peer'].flatten('save-peer', obj, flat)
+ t.strictSame(flat, {saveType: 'peer'}, 'set saveType to peer if unset')
+
+ flat.saveType = 'optional'
+ definitions['save-peer'].flatten('save-peer', obj, flat)
+ t.strictSame(flat, {saveType: 'peerOptional'}, 'set to peerOptional if optional already')
+
+ definitions['save-peer'].flatten('save-peer', obj, flat)
+ t.strictSame(flat, {saveType: 'peerOptional'}, 'no effect if already peerOptional')
+
+ obj['save-peer'] = false
+ definitions['save-peer'].flatten('save-peer', obj, flat)
+ t.strictSame(flat, {saveType: 'optional'}, 'switch peerOptional to optional if false')
+
+ obj['save-peer'] = false
+ flat.saveType = 'peer'
+ definitions['save-peer'].flatten('save-peer', obj, flat)
+ t.strictSame(flat, {}, 'remove saveType if peer and setting false')
+
+ t.end()
+ })
+
+ t.test('save-optional', t => {
+ const obj = { 'save-optional': false}
+ const flat = {}
+ definitions['save-optional'].flatten('save-optional', obj, flat)
+ t.strictSame(flat, {}, 'no effect if false and not yet set')
+
+ obj['save-optional'] = true
+ definitions['save-optional'].flatten('save-optional', obj, flat)
+ t.strictSame(flat, {saveType: 'optional'}, 'set saveType to optional if unset')
+
+ flat.saveType = 'peer'
+ definitions['save-optional'].flatten('save-optional', obj, flat)
+ t.strictSame(flat, {saveType: 'peerOptional'}, 'set to peerOptional if peer already')
+
+ definitions['save-optional'].flatten('save-optional', obj, flat)
+ t.strictSame(flat, {saveType: 'peerOptional'}, 'no effect if already peerOptional')
+
+ obj['save-optional'] = false
+ definitions['save-optional'].flatten('save-optional', obj, flat)
+ t.strictSame(flat, {saveType: 'peer'}, 'switch peerOptional to peer if false')
+
+ flat.saveType = 'optional'
+ definitions['save-optional'].flatten('save-optional', obj, flat)
+ t.strictSame(flat, {}, 'remove saveType if optional and setting false')
+
+ t.end()
+ })
+
+ t.end()
+})
+
+t.test('cafile -> flat.ca', t => {
+ const path = t.testdir({
+ cafile: `
+-----BEGIN CERTIFICATE-----
+XXXX
+XXXX
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+YYYY\r
+YYYY\r
+-----END CERTIFICATE-----
+`,
+ })
+ const cafile = resolve(path, 'cafile')
+
+ const obj = {}
+ const flat = {}
+ definitions.cafile.flatten('cafile', obj, flat)
+ t.strictSame(flat, {}, 'no effect if no cafile set')
+ obj.cafile = resolve(path, 'no/cafile/here')
+ definitions.cafile.flatten('cafile', obj, flat)
+ t.strictSame(flat, {}, 'no effect if cafile not found')
+ obj.cafile = cafile
+ definitions.cafile.flatten('cafile', obj, flat)
+ t.strictSame(flat, {
+ ca: [
+ '-----BEGIN CERTIFICATE-----\nXXXX\nXXXX\n-----END CERTIFICATE-----',
+ '-----BEGIN CERTIFICATE-----\nYYYY\nYYYY\n-----END CERTIFICATE-----',
+ ],
+ })
+ t.test('error other than ENOENT gets thrown', t => {
+ const poo = new Error('poo')
+ const defnReadFileThrows = requireInject(defpath, {
+ fs: {
+ ...require('fs'),
+ readFileSync: () => {
+ throw poo
+ },
+ },
+ })
+ t.throws(() => defnReadFileThrows.cafile.flatten('cafile', obj, {}), poo)
+ t.end()
+ })
+
+ t.end()
+})
+
+t.test('detect CI', t => {
+ const defnNoCI = requireInject(defpath, {
+ '@npmcli/ci-detect': () => false,
+ })
+ const defnCIFoo = requireInject(defpath, {
+ '@npmcli/ci-detect': () => 'foo',
+ })
+ t.equal(defnNoCI['ci-name'].default, null, 'null when not in CI')
+ t.equal(defnCIFoo['ci-name'].default, 'foo', 'name of CI when in CI')
+ t.end()
+})
+
+t.test('user-agent', t => {
+ const obj = {
+ 'user-agent': definitions['user-agent'].default,
+ 'npm-version': '1.2.3',
+ 'node-version': '9.8.7',
+ }
+ const flat = {}
+ const expectNoCI = `npm/1.2.3 node/9.8.7 ` +
+ `${process.platform} ${process.arch}`
+ definitions['user-agent'].flatten('user-agent', obj, flat)
+ t.equal(flat.userAgent, expectNoCI)
+ obj['ci-name'] = 'foo'
+ const expectCI = `${expectNoCI} ci/foo`
+ definitions['user-agent'].flatten('user-agent', obj, flat)
+ t.equal(flat.userAgent, expectCI)
+ t.end()
+})
diff --git a/deps/npm/test/lib/utils/config/describe-all.js b/deps/npm/test/lib/utils/config/describe-all.js
new file mode 100644
index 0000000000..814d92ac95
--- /dev/null
+++ b/deps/npm/test/lib/utils/config/describe-all.js
@@ -0,0 +1,6 @@
+const t = require('tap')
+const describeAll = require('../../../../lib/utils/config/describe-all.js')
+// this basically ends up being a duplicate of the helpdoc dumped into
+// a snapshot, but it verifies that we get the same help output on every
+// platform where we run CI.
+t.matchSnapshot(describeAll())
diff --git a/deps/npm/test/lib/utils/config/flatten.js b/deps/npm/test/lib/utils/config/flatten.js
new file mode 100644
index 0000000000..9fac0820cb
--- /dev/null
+++ b/deps/npm/test/lib/utils/config/flatten.js
@@ -0,0 +1,34 @@
+const t = require('tap')
+const flatten = require('../../../../lib/utils/config/flatten.js')
+
+require.main.filename = '/path/to/npm'
+delete process.env.NODE
+process.execPath = '/path/to/node'
+
+const obj = {
+ 'save-dev': true,
+ '@foobar:registry': 'https://foo.bar.com/',
+ '//foo.bar.com:_authToken': 'foobarbazquuxasdf',
+ userconfig: '/path/to/.npmrc',
+}
+
+const flat = flatten(obj)
+t.strictSame(flat, {
+ saveType: 'dev',
+ '@foobar:registry': 'https://foo.bar.com/',
+ '//foo.bar.com:_authToken': 'foobarbazquuxasdf',
+ npmBin: '/path/to/npm',
+ nodeBin: '/path/to/node',
+ hashAlgorithm: 'sha1',
+})
+
+// now flatten something else on top of it.
+process.env.NODE = '/usr/local/bin/node.exe'
+flatten({ 'save-dev': false }, flat)
+t.strictSame(flat, {
+ '@foobar:registry': 'https://foo.bar.com/',
+ '//foo.bar.com:_authToken': 'foobarbazquuxasdf',
+ npmBin: '/path/to/npm',
+ nodeBin: '/usr/local/bin/node.exe',
+ hashAlgorithm: 'sha1',
+})
diff --git a/deps/npm/test/lib/utils/config/index.js b/deps/npm/test/lib/utils/config/index.js
new file mode 100644
index 0000000000..75d72e784f
--- /dev/null
+++ b/deps/npm/test/lib/utils/config/index.js
@@ -0,0 +1,24 @@
+const t = require('tap')
+const config = require('../../../../lib/utils/config/index.js')
+const flatten = require('../../../../lib/utils/config/flatten.js')
+const definitions = require('../../../../lib/utils/config/definitions.js')
+const describeAll = require('../../../../lib/utils/config/describe-all.js')
+t.matchSnapshot(config.shorthands, 'shorthands')
+
+// just spot check a few of these to show that we got defaults assembled
+t.match(config.defaults, {
+ registry: definitions.registry.default,
+ 'init-module': definitions['init-module'].default,
+})
+
+// is a getter, so changes are reflected
+definitions.registry.default = 'https://example.com'
+t.strictSame(config.defaults.registry, 'https://example.com')
+
+t.strictSame(config, {
+ defaults: config.defaults,
+ shorthands: config.shorthands,
+ flatten,
+ definitions,
+ describeAll,
+})
diff --git a/deps/npm/test/lib/utils/did-you-mean.js b/deps/npm/test/lib/utils/did-you-mean.js
index 0c9c95c7f9..68893a800f 100644
--- a/deps/npm/test/lib/utils/did-you-mean.js
+++ b/deps/npm/test/lib/utils/did-you-mean.js
@@ -1,7 +1,39 @@
const t = require('tap')
+const requireInject = require('require-inject')
+const npm = requireInject('../../../lib/npm.js')
+
const dym = require('../../../lib/utils/did-you-mean.js')
-t.equal(dym('asdfa', ['asdf', 'asfd', 'adfs', 'safd', 'foobarbaz', 'foobar']),
- '\nDid you mean this?\n asdf')
-t.equal(dym('asdfa', ['asdf', 'sdfa', 'foo', 'bar', 'fdsa']),
- '\nDid you mean one of these?\n asdf\n sdfa')
-t.equal(dym('asdfa', ['install', 'list', 'test']), '')
+t.test('did-you-mean', t => {
+ npm.load(err => {
+ t.notOk(err)
+ t.test('nistall', async t => {
+ const result = await dym(npm, npm.localPrefix, 'nistall')
+ t.match(result, 'npm install')
+ })
+ t.test('sttest', async t => {
+ const result = await dym(npm, npm.localPrefix, 'sttest')
+ t.match(result, 'npm test')
+ t.match(result, 'npm run posttest')
+ })
+ t.test('npz', async t => {
+ const result = await dym(npm, npm.localPrefix, 'npxx')
+ t.match(result, 'npm exec npx')
+ })
+ t.test('qwuijbo', async t => {
+ const result = await dym(npm, npm.localPrefix, 'qwuijbo')
+ t.match(result, '')
+ })
+ t.end()
+ })
+})
+
+t.test('missing bin and script properties', async t => {
+ const path = t.testdir({
+ 'package.json': JSON.stringify({
+ name: 'missing-bin',
+ }),
+ })
+
+ const result = await dym(npm, path, 'nistall')
+ t.match(result, 'npm install')
+})
diff --git a/deps/npm/test/lib/utils/flat-options.js b/deps/npm/test/lib/utils/flat-options.js
deleted file mode 100644
index 6f580fabc4..0000000000
--- a/deps/npm/test/lib/utils/flat-options.js
+++ /dev/null
@@ -1,359 +0,0 @@
-const t = require('tap')
-
-process.env.NODE = '/path/to/some/node'
-process.env.NODE_ENV = 'development'
-
-const logs = []
-const log = require('npmlog')
-log.warn = (...args) => logs.push(['warn', ...args])
-log.verbose = (...args) => logs.push(['verbose', ...args])
-
-class Mocknpm {
- constructor (opts = {}) {
- this.modes = {
- exec: 0o777,
- file: 0o666,
- umask: 0o22,
- }
- this.color = true
- this.projectScope = '@npmcli'
- this.tmp = '/tmp'
- this.command = null
- this.globalPrefix = '/usr/local'
- this.localPrefix = '/path/to/npm/cli'
- this.prefix = this.localPrefix
- this.version = '7.6.5'
- this.config = new MockConfig(opts)
- this.flatOptions = null
- }
-}
-
-class MockConfig {
- constructor (opts = {}) {
- this.list = [{
- cache: 'cache',
- 'node-version': '1.2.3',
- global: 'global',
- registry: 'registry',
- access: 'access',
- 'always-auth': 'always-auth',
- audit: 'audit',
- 'audit-level': 'audit-level',
- 'auth-type': 'auth-type',
- before: 'before',
- browser: 'browser',
- ca: 'ca',
- cafile: 'cafile',
- call: 'call',
- cert: 'cert',
- key: 'key',
- 'cache-lock-retries': 'cache-lock-retries',
- 'cache-lock-stale': 'cache-lock-stale',
- 'cache-lock-wait': 'cache-lock-wait',
- cidr: 'cidr',
- 'read-only': 'read-only',
- preid: 'preid',
- 'tag-version-prefix': 'tag-version-prefix',
- 'allow-same-version': 'allow-same-version',
- message: 'message',
- 'commit-hooks': 'commit-hooks',
- 'git-tag-version': 'git-tag-version',
- 'sign-git-commit': 'sign-git-commit',
- 'sign-git-tag': 'sign-git-tag',
- depth: 'depth',
- description: 'description',
- searchexclude: 'searchexclude',
- searchlimit: 'searchlimit',
- searchopts: 'from=1',
- searchstaleness: 'searchstaleness',
- 'dry-run': 'dry-run',
- 'engine-strict': 'engine-strict',
- 'fetch-retries': 'fetch-retries',
- 'fetch-retry-factor': 'fetch-retry-factor',
- 'fetch-retry-mintimeout': 'fetch-retry-mintimeout',
- 'fetch-retry-maxtimeout': 'fetch-retry-maxtimeout',
- 'fetch-timeout': 'fetch-timeout',
- force: 'force',
- 'format-package-lock': 'format-package-lock',
- fund: 'fund',
- git: 'git',
- viewer: 'viewer',
- editor: 'editor',
- 'bin-links': 'bin-links',
- 'rebuild-bundle': 'rebuild-bundle',
- package: 'package',
- 'package-lock': 'package-lock',
- 'package-lock-only': 'package-lock-only',
- 'global-style': 'global-style',
- 'legacy-bundling': 'legacy-bundling',
- 'script-shell': 'script-shell',
- omit: [],
- include: [],
- save: 'save',
- 'save-bundle': 'save-bundle',
- 'save-dev': 'save-dev',
- 'save-optional': 'save-optional',
- 'save-peer': 'save-peer',
- 'save-prod': 'save-prod',
- 'save-exact': 'save-exact',
- 'save-prefix': 'save-prefix',
- otp: 'otp',
- offline: 'offline',
- 'prefer-online': 'prefer-online',
- 'prefer-offline': 'prefer-offline',
- 'cache-max': 'cache-max',
- 'cache-min': 'cache-min',
- 'strict-ssl': 'strict-ssl',
- scope: '',
- tag: 'tag',
- 'user-agent': 'user-agent',
- '@scope:registry': '@scope:registry',
- '//nerf.dart:_authToken': '//nerf.dart:_authToken',
- proxy: 'proxy',
- noproxy: 'noproxy',
- ...opts,
- }]
- }
-
- get (key) {
- return this.list[0][key]
- }
-
- set (key, val) {
- this.list[0][key] = val
- }
-}
-
-const flatOptions = require('../../../lib/utils/flat-options.js')
-t.match(logs, [[
- 'verbose',
- 'npm-session',
- /^[0-9a-f]{16}$/,
-]], 'logged npm session verbosely')
-logs.length = 0
-
-t.test('basic', t => {
- const npm = new Mocknpm()
- const generatedFlat = flatOptions(npm)
- const clean = {
- ...generatedFlat,
- npmBin: '/path/to/npm/bin.js',
- log: {},
- npmSession: '12345',
- cache: generatedFlat.cache.replace(/\\/g, '/'),
- }
- t.matchSnapshot(clean, 'flat options')
- t.equal(generatedFlat.npmCommand, null, 'command not set yet')
- npm.command = 'view'
- t.equal(generatedFlat.npmCommand, 'view', 'command updated via getter')
- t.equal(generatedFlat.npmBin, require.main.filename)
- // test the object is frozen
- generatedFlat.newField = 'asdf'
- t.equal(generatedFlat.newField, undefined, 'object is frozen')
- const preExistingOpts = { flat: 'options' }
- npm.flatOptions = preExistingOpts
- t.equal(flatOptions(npm), preExistingOpts, 'use pre-existing npm.flatOptions')
- t.end()
-})
-
-t.test('get preferOffline from cache-min', t => {
- const npm = new Mocknpm({
- 'cache-min': 9999999,
- 'prefer-offline': undefined,
- })
- const opts = flatOptions(npm)
- t.equal(opts.preferOffline, true, 'got preferOffline from cache min')
- logs.length = 0
- t.equal(opts.cacheMin, undefined, 'opts.cacheMin is not set')
- t.match(logs, [])
- logs.length = 0
- t.end()
-})
-
-t.test('get preferOnline from cache-max', t => {
- const npm = new Mocknpm({
- 'cache-max': -1,
- 'prefer-online': undefined,
- })
- const opts = flatOptions(npm)
- t.equal(opts.preferOnline, true, 'got preferOnline from cache min')
- logs.length = 0
- t.equal(opts.cacheMax, undefined, 'opts.cacheMax is not set')
- t.match(logs, [])
- logs.length = 0
- t.end()
-})
-
-t.test('tag emits warning', t => {
- const npm = new Mocknpm({ tag: 'foobar' })
- t.equal(flatOptions(npm).tag, 'foobar', 'tag is foobar')
- t.match(logs, [])
- logs.length = 0
- t.end()
-})
-
-t.test('omit/include options', t => {
- t.test('omit explicitly', t => {
- const { NODE_ENV } = process.env
- const npm = new Mocknpm({
- omit: ['dev', 'optional', 'peer'],
- })
- t.strictSame(flatOptions(npm).omit, ['dev', 'optional', 'peer'])
- t.equal(process.env.NODE_ENV, 'production')
- process.env.NODE_ENV = NODE_ENV
- t.end()
- })
-
- t.test('omit and include some', t => {
- const { NODE_ENV } = process.env
- const npm = new Mocknpm({
- omit: ['dev', 'optional', 'peer'],
- include: ['peer'],
- })
- t.strictSame(flatOptions(npm).omit, ['dev', 'optional'])
- t.equal(process.env.NODE_ENV, 'production')
- process.env.NODE_ENV = NODE_ENV
- t.end()
- })
-
- t.test('dev flag', t => {
- const { NODE_ENV } = process.env
- const npm = new Mocknpm({
- omit: ['dev', 'optional', 'peer'],
- include: [],
- dev: true,
- })
- t.strictSame(flatOptions(npm).omit, ['optional', 'peer'])
- t.equal(process.env.NODE_ENV, NODE_ENV)
- process.env.NODE_ENV = NODE_ENV
- t.end()
- })
-
- t.test('production flag', t => {
- const { NODE_ENV } = process.env
- const npm = new Mocknpm({
- omit: [],
- include: [],
- production: true,
- })
- t.strictSame(flatOptions(npm).omit, ['dev'])
- t.equal(process.env.NODE_ENV, 'production')
- process.env.NODE_ENV = NODE_ENV
- t.end()
- })
-
- t.test('only', t => {
- const { NODE_ENV } = process.env
- const cases = ['prod', 'production']
- t.plan(cases.length)
- cases.forEach(c => t.test(c, t => {
- const npm = new Mocknpm({
- omit: [],
- include: [],
- only: c,
- })
- t.strictSame(flatOptions(npm).omit, ['dev'])
- t.equal(process.env.NODE_ENV, 'production')
- process.env.NODE_ENV = NODE_ENV
- t.end()
- }))
- })
-
- t.test('also dev', t => {
- const { NODE_ENV } = process.env
- const npm = new Mocknpm({
- omit: ['dev', 'optional', 'peer'],
- also: 'dev',
- })
- t.strictSame(flatOptions(npm).omit, ['optional', 'peer'])
- t.equal(process.env.NODE_ENV, NODE_ENV)
- process.env.NODE_ENV = NODE_ENV
- t.end()
- })
-
- t.test('no-optional', t => {
- const { NODE_ENV } = process.env
- const npm = new Mocknpm({
- optional: false,
- omit: null,
- include: null,
- })
- t.strictSame(flatOptions(npm).omit, ['optional'])
- t.equal(process.env.NODE_ENV, NODE_ENV)
- process.env.NODE_ENV = NODE_ENV
- t.end()
- })
-
- t.end()
-})
-
-t.test('get the node without the environ', t => {
- delete process.env.NODE
- t.equal(flatOptions(new Mocknpm()).nodeBin, process.execPath)
- t.end()
-})
-
-t.test('various default values and falsey fallbacks', t => {
- const npm = new Mocknpm({
- 'script-shell': false,
- registry: 'http://example.com',
- searchlimit: 0,
- 'save-exact': false,
- 'save-prefix': '>=',
- })
- const opts = flatOptions(npm)
- t.equal(opts.scriptShell, undefined, 'scriptShell is undefined if falsey')
- t.equal(opts.search.limit, 20, 'searchLimit defaults to 20')
- t.equal(opts.savePrefix, '>=', 'save-prefix respected if no save-exact')
- t.equal(opts.scope, '', 'scope defaults to empty string')
- logs.length = 0
- t.end()
-})
-
-t.test('legacy _auth token', t => {
- const npm = new Mocknpm({
- _auth: 'asdfasdf',
- })
- t.strictSame(
- flatOptions(npm)._auth,
- 'asdfasdf',
- 'should set legacy _auth token'
- )
- t.end()
-})
-
-t.test('save-type', t => {
- const base = {
- 'save-optional': false,
- 'save-peer': false,
- 'save-dev': false,
- 'save-prod': false,
- }
- const cases = [
- ['peerOptional', {
- 'save-optional': true,
- 'save-peer': true,
- }],
- ['optional', {
- 'save-optional': true,
- }],
- ['dev', {
- 'save-dev': true,
- }],
- ['peer', {
- 'save-peer': true,
- }],
- ['prod', {
- 'save-prod': true,
- }],
- [null, {}],
- ]
- for (const [expect, options] of cases) {
- const opts = flatOptions(new Mocknpm({
- ...base,
- ...options,
- }))
- t.equal(opts.saveType, expect, JSON.stringify(options))
- }
- t.end()
-})
diff --git a/deps/npm/test/lib/utils/lifecycle-cmd.js b/deps/npm/test/lib/utils/lifecycle-cmd.js
index 3e3a7da434..862c87a8e0 100644
--- a/deps/npm/test/lib/utils/lifecycle-cmd.js
+++ b/deps/npm/test/lib/utils/lifecycle-cmd.js
@@ -10,6 +10,7 @@ const npm = {
},
}
t.test('create a lifecycle command', t => {
+ t.plan(5)
class TestStage extends LifecycleCmd {
static get name () {
return 'test-stage'
@@ -20,6 +21,9 @@ t.test('create a lifecycle command', t => {
cmd.exec(['some', 'args'], (er, result) => {
t.same(runArgs, ['test-stage', 'some', 'args'])
t.strictSame(result, 'called npm.commands.run')
- t.end()
+ })
+ cmd.execWorkspaces(['some', 'args'], [], (er, result) => {
+ t.same(runArgs, ['test-stage', 'some', 'args'])
+ t.strictSame(result, 'called npm.commands.run')
})
})
diff --git a/deps/npm/test/lib/utils/npm-usage.js b/deps/npm/test/lib/utils/npm-usage.js
index fbc453811e..ebf637ae1c 100644
--- a/deps/npm/test/lib/utils/npm-usage.js
+++ b/deps/npm/test/lib/utils/npm-usage.js
@@ -1,12 +1,5 @@
const t = require('tap')
-
-const OUTPUT = []
-const output = (...msg) => OUTPUT.push(msg)
-const requireInject = require('require-inject')
-const usage = require('../../../lib/utils/npm-usage.js')
-
-const npm = requireInject('../../../lib/npm.js')
-npm.output = output
+const npm = require('../../../lib/npm.js')
t.test('usage', t => {
t.afterEach((cb) => {
@@ -29,61 +22,19 @@ t.test('usage', t => {
npm.config.set('userconfig', '/some/config/file/.npmrc')
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.matchSnapshot(npm.usage)
t.end()
})
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.matchSnapshot(npm.usage)
t.end()
})
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.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.matchSnapshot(npm.usage)
t.end()
})
@@ -106,11 +57,7 @@ t.test('usage', t => {
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.matchSnapshot(npm.usage)
t.end()
})
}
diff --git a/deps/npm/test/lib/utils/read-local-package.js b/deps/npm/test/lib/utils/read-local-package.js
index 9ae21f7d62..4b693afb48 100644
--- a/deps/npm/test/lib/utils/read-local-package.js
+++ b/deps/npm/test/lib/utils/read-local-package.js
@@ -1,22 +1,17 @@
const requireInject = require('require-inject')
const { test } = require('tap')
+const mockNpm = require('../../fixtures/mock-npm')
-let prefix
-const _flatOptions = {
+const config = {
json: false,
global: false,
- get prefix () {
- return prefix
- },
}
+const npm = mockNpm({ config })
const readLocalPackageName = requireInject('../../../lib/utils/read-local-package.js')
-const npm = {
- flatOptions: _flatOptions,
-}
test('read local package.json', async (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: 'my-local-package',
version: '1.0.0',
@@ -31,7 +26,7 @@ test('read local package.json', async (t) => {
})
test('read local scoped-package.json', async (t) => {
- prefix = t.testdir({
+ npm.prefix = t.testdir({
'package.json': JSON.stringify({
name: '@my-scope/my-local-package',
version: '1.0.0',
@@ -46,13 +41,13 @@ test('read local scoped-package.json', async (t) => {
})
test('read using --global', async (t) => {
- prefix = t.testdir({})
- _flatOptions.global = true
+ npm.prefix = t.testdir({})
+ config.global = true
const packageName = await readLocalPackageName(npm)
t.equal(
packageName,
undefined,
'should not retrieve a package name'
)
- _flatOptions.global = false
+ config.global = false
})
diff --git a/deps/npm/test/lib/utils/tar.js b/deps/npm/test/lib/utils/tar.js
index b780a73e5e..d9b8c5584a 100644
--- a/deps/npm/test/lib/utils/tar.js
+++ b/deps/npm/test/lib/utils/tar.js
@@ -101,9 +101,9 @@ test('should getContents of a tarball', async (t) => {
id: 'my-cool-pkg@1.0.0',
name: 'my-cool-pkg',
version: '1.0.0',
- size: 149,
+ size: 146,
unpackedSize: 49,
- shasum: 'c0bfd67a5142104e429afda09119eedd6a30d2fc',
+ shasum: 'b8379c5e69693cdda73aec3d81dae1d11c1e75bd',
integrity: ssri.parse(integrity.sha512[0]),
filename: 'my-cool-pkg-1.0.0.tgz',
files: [{ path: 'package.json', size: 49, mode: 420 }],
diff --git a/deps/npm/test/lib/version.js b/deps/npm/test/lib/version.js
index a8fcd831fb..35d3d92cd2 100644
--- a/deps/npm/test/lib/version.js
+++ b/deps/npm/test/lib/version.js
@@ -1,21 +1,23 @@
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
let result = []
const noop = () => null
-const npm = {
- flatOptions: {
- tagVersionPrefix: 'v',
- json: false,
- },
+const config = {
+ 'tag-version-prefix': 'v',
+ json: false,
+}
+const npm = mockNpm({
+ config,
prefix: '',
version: '1.0.0',
output: (...msg) => {
for (const m of msg)
result.push(m)
},
-}
+})
const mocks = {
libnpmversion: noop,
}
@@ -25,7 +27,7 @@ const version = new Version(npm)
const _processVersions = process.versions
t.afterEach(cb => {
- npm.flatOptions.json = false
+ config.json = false
npm.prefix = ''
process.versions = _processVersions
result = []
@@ -116,7 +118,7 @@ t.test('failure reading package.json', t => {
t.test('--json option', t => {
const prefix = t.testdir({})
- npm.flatOptions.json = true
+ config.json = true
npm.prefix = prefix
Object.defineProperty(process, 'versions', { value: {} })
@@ -140,8 +142,6 @@ t.test('with one arg', t => {
t.deepEqual(
opts,
{
- tagVersionPrefix: 'v',
- json: false,
path: '',
},
'should forward expected options'
diff --git a/deps/npm/test/lib/view.js b/deps/npm/test/lib/view.js
index 1363a5b9f9..d136a1f418 100644
--- a/deps/npm/test/lib/view.js
+++ b/deps/npm/test/lib/view.js
@@ -1,5 +1,6 @@
const t = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
let logs
const cleanLogs = (done) => {
@@ -243,34 +244,33 @@ t.test('should log package info', t => {
packument,
},
})
- const view = new View({
- flatOptions: {
- global: false,
- },
+ const npm = mockNpm({
+ config: { global: false },
})
+ const view = new View(npm)
const ViewJson = requireInject('../../lib/view.js', {
pacote: {
packument,
},
})
- const viewJson = new ViewJson({
- flatOptions: {
- json: true,
- },
+ const jsonNpm = mockNpm({
+ config: { json: true },
})
+ const viewJson = new ViewJson(jsonNpm)
const ViewUnicode = requireInject('../../lib/view.js', {
pacote: {
packument,
},
})
- const viewUnicode = new ViewUnicode({
- flatOptions: {
+ const unicodeNpm = mockNpm({
+ config: {
global: false,
unicode: true,
},
})
+ const viewUnicode = new ViewUnicode(unicodeNpm)
t.test('package with license, bugs, repository and other fields', t => {
view.exec(['green@1.0.0'], () => {
@@ -351,13 +351,14 @@ t.test('should log info of package in current working dir', t => {
packument,
},
})
- const view = new View({
+ const npm = mockNpm({
prefix: testDir,
- flatOptions: {
- defaultTag: '1.0.0',
+ config: {
+ tag: '1.0.0',
global: false,
},
})
+ const view = new View(npm)
t.test('specific version', t => {
view.exec(['.@1.0.0'], () => {
@@ -382,23 +383,24 @@ t.test('should log info by field name', t => {
packument,
},
})
- const viewJson = new ViewJson({
- flatOptions: {
+ const jsonNpm = mockNpm({
+ config: {
json: true,
global: false,
},
})
+ const viewJson = new ViewJson(jsonNpm)
+
const View = requireInject('../../lib/view.js', {
pacote: {
packument,
},
})
- const view = new View({
- flatOptions: {
- global: false,
- },
+ const npm = mockNpm({
+ config: { global: false },
})
+ const view = new View(npm)
t.test('readme', t => {
view.exec(['yellow@1.0.0', 'readme'], () => {
@@ -468,11 +470,10 @@ t.test('should log info by field name', t => {
t.test('throw error if global mode', (t) => {
const View = requireInject('../../lib/view.js')
- const view = new View({
- flatOptions: {
- global: true,
- },
+ const npm = mockNpm({
+ config: { global: true },
})
+ const view = new View(npm)
view.exec([], (err) => {
t.equals(err.message, 'Cannot use view command in global mode.')
t.end()
@@ -483,12 +484,11 @@ t.test('throw ENOENT error if package.json misisng', (t) => {
const testDir = t.testdir({})
const View = requireInject('../../lib/view.js')
- const view = new View({
+ const npm = mockNpm({
prefix: testDir,
- flatOptions: {
- global: false,
- },
+ config: { global: false },
})
+ const view = new View(npm)
view.exec([], (err) => {
t.match(err, { code: 'ENOENT' })
t.end()
@@ -501,12 +501,11 @@ t.test('throw EJSONPARSE error if package.json not json', (t) => {
})
const View = requireInject('../../lib/view.js')
- const view = new View({
+ const npm = mockNpm({
prefix: testDir,
- flatOptions: {
- global: false,
- },
+ config: { global: false },
})
+ const view = new View(npm)
view.exec([], (err) => {
t.match(err, { code: 'EJSONPARSE' })
t.end()
@@ -519,12 +518,11 @@ t.test('throw error if package.json has no name', (t) => {
})
const View = requireInject('../../lib/view.js')
- const view = new View({
+ const npm = mockNpm({
prefix: testDir,
- flatOptions: {
- global: false,
- },
+ config: { global: false },
})
+ const view = new View(npm)
view.exec([], (err) => {
t.equals(err.message, 'Invalid package.json, no "name" field')
t.end()
@@ -537,12 +535,13 @@ t.test('throws when unpublished', (t) => {
packument,
},
})
- const view = new View({
- flatOptions: {
- defaultTag: '1.0.1',
+ const npm = mockNpm({
+ config: {
+ tag: '1.0.1',
global: false,
},
})
+ const view = new View(npm)
view.exec(['red'], (err) => {
t.equals(err.code, 'E404')
t.end()
@@ -555,12 +554,13 @@ t.test('completion', async t => {
packument,
},
})
- const view = new View({
- flatOptions: {
- defaultTag: '1.0.1',
+ const npm = mockNpm({
+ config: {
+ tag: '1.0.1',
global: false,
},
})
+ const view = new View(npm)
const res = await view.completion({
conf: { argv: { remain: ['npm', 'view', 'green@1.0.0'] } },
})
@@ -570,11 +570,13 @@ t.test('completion', async t => {
t.test('no registry completion', async t => {
const View = requireInject('../../lib/view.js')
- const view = new View({
- flatOptions: {
- defaultTag: '1.0.1',
+ const npm = mockNpm({
+ config: {
+ tag: '1.0.1',
+ global: false,
},
})
+ const view = new View(npm)
const res = await view.completion({conf: { argv: { remain: ['npm', 'view'] } } })
t.notOk(res, 'there is no package completion')
t.end()
diff --git a/deps/npm/test/lib/whoami.js b/deps/npm/test/lib/whoami.js
index 1a1ecd2574..b242ea8941 100644
--- a/deps/npm/test/lib/whoami.js
+++ b/deps/npm/test/lib/whoami.js
@@ -1,18 +1,21 @@
const { test } = require('tap')
const requireInject = require('require-inject')
+const mockNpm = require('../fixtures/mock-npm')
test('whoami', (t) => {
t.plan(3)
const Whoami = requireInject('../../lib/whoami.js', {
'../../lib/utils/get-identity.js': () => Promise.resolve('foo'),
})
- const whoami = new Whoami({
- flatOptions: {},
+ const npm = mockNpm({
+ config: { json: false },
output: (output) => {
t.equal(output, 'foo', 'should output the username')
},
})
+ const whoami = new Whoami(npm)
+
whoami.exec([], (err) => {
t.ifError(err, 'npm whoami')
t.ok('should successfully print username')
@@ -24,12 +27,13 @@ test('whoami json', (t) => {
const Whoami = requireInject('../../lib/whoami.js', {
'../../lib/utils/get-identity.js': () => Promise.resolve('foo'),
})
- const whoami = new Whoami({
- flatOptions: { json: true },
+ const npm = mockNpm({
+ config: { json: true },
output: (output) => {
- t.equal(output, '"foo"', 'should output the username as json')
+ t.equal(output, '"foo"', 'should output the username')
},
})
+ const whoami = new Whoami(npm)
whoami.exec([], (err) => {
t.ifError(err, 'npm whoami')
diff --git a/deps/npm/test/lib/workspaces/get-workspaces.js b/deps/npm/test/lib/workspaces/get-workspaces.js
new file mode 100644
index 0000000000..ebed9dd35c
--- /dev/null
+++ b/deps/npm/test/lib/workspaces/get-workspaces.js
@@ -0,0 +1,199 @@
+const { resolve } = require('path')
+const t = require('tap')
+const getWorkspaces = require('../../../lib/workspaces/get-workspaces.js')
+
+const normalizePath = p => p
+ .replace(/\\+/g, '/')
+ .replace(/\r\n/g, '\n')
+
+const cleanOutput = (str, path) => normalizePath(str)
+ .replace(normalizePath(path), '{PATH}')
+
+const clean = (res, path) => {
+ const cleaned = new Map()
+ for (const [key, value] of res.entries())
+ cleaned.set(key, cleanOutput(value, path))
+ return cleaned
+}
+
+t.test('get-workspaces', async t => {
+ const path = t.testdir({
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ scripts: { glorp: 'echo a doing the glerp glop' },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '2.0.0',
+ scripts: { glorp: 'echo b doing the glerp glop' },
+ }),
+ },
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ scripts: {
+ test: 'exit 0',
+ posttest: 'echo posttest',
+ lorem: 'echo c lorem',
+ },
+ }),
+ },
+ d: {
+ 'package.json': JSON.stringify({
+ name: 'd',
+ version: '1.0.0',
+ scripts: {
+ test: 'exit 0',
+ posttest: 'echo posttest',
+ },
+ }),
+ },
+ e: {
+ 'package.json': JSON.stringify({
+ name: 'e',
+ scripts: { test: 'exit 0', start: 'echo start something' },
+ }),
+ },
+ noscripts: {
+ 'package.json': JSON.stringify({
+ name: 'noscripts',
+ version: '1.0.0',
+ }),
+ },
+ },
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ workspaces: ['packages/*'],
+ }),
+ })
+
+ let workspaces
+
+ workspaces = await getWorkspaces(['a', 'b'], { path })
+ t.deepEqual(
+ clean(workspaces, path),
+ new Map(Object.entries({
+ a: '{PATH}/packages/a',
+ b: '{PATH}/packages/b',
+ })),
+ 'should filter by package name'
+ )
+
+ workspaces = await getWorkspaces(['./packages/c'], { path })
+ t.deepEqual(
+ clean(workspaces, path),
+ new Map(Object.entries({
+ c: '{PATH}/packages/c',
+ })),
+ 'should filter by package directory'
+ )
+
+ workspaces = await getWorkspaces(['packages/c'], { path })
+ t.deepEqual(
+ clean(workspaces, path),
+ new Map(Object.entries({
+ c: '{PATH}/packages/c',
+ })),
+ 'should filter by rel package directory'
+ )
+
+ workspaces = await getWorkspaces([resolve(path, 'packages/c')], { path })
+ t.deepEqual(
+ clean(workspaces, path),
+ new Map(Object.entries({
+ c: '{PATH}/packages/c',
+ })),
+ 'should filter by absolute package directory'
+ )
+
+ workspaces = await getWorkspaces(['packages'], { path })
+ t.deepEqual(
+ clean(workspaces, path),
+ new Map(Object.entries({
+ a: '{PATH}/packages/a',
+ b: '{PATH}/packages/b',
+ c: '{PATH}/packages/c',
+ d: '{PATH}/packages/d',
+ e: '{PATH}/packages/e',
+ noscripts: '{PATH}/packages/noscripts',
+ })),
+ 'should filter by parent directory name'
+ )
+
+ workspaces = await getWorkspaces(['./packages/'], { path })
+ t.deepEqual(
+ clean(workspaces, path),
+ new Map(Object.entries({
+ a: '{PATH}/packages/a',
+ b: '{PATH}/packages/b',
+ c: '{PATH}/packages/c',
+ d: '{PATH}/packages/d',
+ e: '{PATH}/packages/e',
+ noscripts: '{PATH}/packages/noscripts',
+ })),
+ 'should filter by parent directory path'
+ )
+
+ workspaces = await getWorkspaces([resolve(path, './packages')], { path })
+ t.deepEqual(
+ clean(workspaces, path),
+ new Map(Object.entries({
+ a: '{PATH}/packages/a',
+ b: '{PATH}/packages/b',
+ c: '{PATH}/packages/c',
+ d: '{PATH}/packages/d',
+ e: '{PATH}/packages/e',
+ noscripts: '{PATH}/packages/noscripts',
+ })),
+ 'should filter by absolute parent directory path'
+ )
+
+ workspaces = await getWorkspaces([], { path })
+ t.deepEqual(
+ clean(workspaces, path),
+ new Map(Object.entries({
+ a: '{PATH}/packages/a',
+ b: '{PATH}/packages/b',
+ c: '{PATH}/packages/c',
+ d: '{PATH}/packages/d',
+ e: '{PATH}/packages/e',
+ noscripts: '{PATH}/packages/noscripts',
+ })),
+ 'should return all workspaces if no filter set'
+ )
+
+ try {
+ await getWorkspaces(['missing'], { path })
+ throw new Error('missed throw')
+ } catch (err) {
+ t.match(
+ err,
+ /No workspaces found/,
+ 'should throw no workspaces found error'
+ )
+ }
+
+ const unconfiguredWorkspaces = t.testdir({
+ 'package.json': JSON.stringify({
+ name: 'no-configured-workspaces',
+ version: '1.0.0',
+ }),
+ })
+ try {
+ await getWorkspaces([], { path: unconfiguredWorkspaces })
+ throw new Error('missed throw')
+ } catch (err) {
+ t.match(
+ err,
+ /No workspaces found/,
+ 'should throw no workspaces found error'
+ )
+ }
+})