diff options
67 files changed, 1228 insertions, 1207 deletions
diff --git a/lib/access.js b/lib/access.js index 0df36beea..3020719a7 100644 --- a/lib/access.js +++ b/lib/access.js @@ -75,7 +75,7 @@ class Access extends BaseCommand { if (!subcommands.includes(cmd) || !this[cmd]) throw this.usageError(`${cmd} is not a recognized subcommand.`) - return this[cmd](args, { ...this.npm.flatOptions }) + return this[cmd](args, this.npm.flatOptions) } public ([pkg], opts) { diff --git a/lib/audit.js b/lib/audit.js index 6e64987b6..27cebff9f 100644 --- a/lib/audit.js +++ b/lib/audit.js @@ -37,11 +37,14 @@ class Audit extends BaseCommand { } async audit (args) { - const arb = new Arborist({ + const reporter = this.npm.config.get('json') ? 'json' : 'detail' + const opts = { ...this.npm.flatOptions, audit: true, path: this.npm.prefix, - }) + reporter, + } + const arb = new Arborist(opts) const fix = args[0] === 'fix' await arb.audit({ fix }) if (fix) @@ -49,11 +52,7 @@ class Audit extends BaseCommand { else { // will throw if there's an error, because this is an audit command auditError(this.npm, arb.auditReport) - const reporter = this.npm.flatOptions.json ? 'json' : 'detail' - const result = auditReport(arb.auditReport, { - ...this.npm.flatOptions, - reporter, - }) + const result = auditReport(arb.auditReport, opts) process.exitCode = process.exitCode || result.exitCode this.npm.output(result.report) } diff --git a/lib/bin.js b/lib/bin.js index 1450fb539..b0acefef9 100644 --- a/lib/bin.js +++ b/lib/bin.js @@ -17,7 +17,7 @@ class Bin extends BaseCommand { async bin (args) { const b = this.npm.bin this.npm.output(b) - if (this.npm.flatOptions.global && !envPath.includes(b)) + if (this.npm.config.get('global') && !envPath.includes(b)) console.error('(not in PATH env variable)') } } diff --git a/lib/cache.js b/lib/cache.js index 80a5c68eb..b2d42ab23 100644 --- a/lib/cache.js +++ b/lib/cache.js @@ -63,7 +63,7 @@ class Cache extends BaseCommand { throw new Error('npm cache clear does not accept arguments') const cachePath = path.join(this.npm.cache, '_cacache') - if (!this.npm.flatOptions.force) { + if (!this.npm.config.get('force')) { throw new Error(`As of npm@5, the npm cache self-heals from corruption issues by treating integrity mismatches as cache misses. As a result, data extracted from the cache is guaranteed to be valid. If you @@ -100,7 +100,6 @@ with --force.`) throw Object.assign(new Error(usage), { code: 'EUSAGE' }) log.silly('cache add', 'spec', spec) - const opts = { ...this.npm.flatOptions } // we ask pacote for the thing, and then just throw the data // away so that it tee-pipes it into the cache like it does @@ -108,7 +107,7 @@ with --force.`) await pacote.tarball.stream(spec, stream => { stream.resume() return stream.promise() - }, opts) + }, this.npm.flatOptions) } async verify () { @@ -30,14 +30,13 @@ class CI extends BaseCommand { } async ci () { - if (this.npm.flatOptions.global) { + if (this.npm.config.get('global')) { const err = new Error('`npm ci` does not work for global packages') err.code = 'ECIGLOBAL' throw err } const where = this.npm.prefix - const { scriptShell, ignoreScripts } = this.npm.flatOptions const arb = new Arborist({ ...this.npm.flatOptions, path: where }) await Promise.all([ @@ -54,6 +53,7 @@ class CI extends BaseCommand { // npm ci should never modify the lockfile or package.json await arb.reify({ ...this.npm.flatOptions, save: false }) + const ignoreScripts = this.npm.config.get('ignore-scripts') // run the same set of scripts that `npm install` runs. if (!ignoreScripts) { const scripts = [ @@ -65,6 +65,7 @@ class CI extends BaseCommand { 'prepare', 'postprepare', ] + const scriptShell = this.npm.config.get('script-shell') || undefined for (const event of scripts) { await runScript({ path: where, diff --git a/lib/dedupe.js b/lib/dedupe.js index 50a56211f..4dd759dac 100644 --- a/lib/dedupe.js +++ b/lib/dedupe.js @@ -23,12 +23,13 @@ class Dedupe extends BaseCommand { const dryRun = this.npm.config.get('dry-run') const where = this.npm.prefix - const arb = new Arborist({ + const opts = { ...this.npm.flatOptions, path: where, dryRun, - }) - await arb.dedupe(this.npm.flatOptions) + } + const arb = new Arborist(opts) + await arb.dedupe(opts) await reifyFinish(this.npm, arb) } } diff --git a/lib/diff.js b/lib/diff.js index 0e322ec64..221213365 100644 --- a/lib/diff.js +++ b/lib/diff.js @@ -30,7 +30,7 @@ class Diff extends BaseCommand { get where () { const globalTop = resolve(this.npm.globalDir, '..') - const { global } = this.npm.flatOptions + const global = this.npm.config.get('global') return global ? globalTop : this.npm.prefix } @@ -39,7 +39,7 @@ class Diff extends BaseCommand { } async diff (args) { - const specs = this.npm.flatOptions.diff.filter(d => d) + const specs = this.npm.config.get('diff').filter(d => d) if (specs.length > 2) { throw new TypeError( 'Can\'t use more than two --diff arguments.\n\n' + @@ -91,7 +91,7 @@ class Diff extends BaseCommand { } return [ - `${pkgName}@${this.npm.flatOptions.defaultTag}`, + `${pkgName}@${this.npm.config.get('tag')}`, `file:${this.npm.prefix}`, ] } diff --git a/lib/dist-tag.js b/lib/dist-tag.js index cdc95ac6f..81773a40a 100644 --- a/lib/dist-tag.js +++ b/lib/dist-tag.js @@ -61,7 +61,7 @@ class DistTag extends BaseCommand { async add (spec, tag, opts) { spec = npa(spec || '') const version = spec.rawSpec - const defaultTag = tag || opts.defaultTag + const defaultTag = tag || this.npm.config.get('tag') log.verbose('dist-tag add', defaultTag, 'to', spec.name + '@' + version) diff --git a/lib/exec.js b/lib/exec.js index b2443b17a..8c8606456 100644 --- a/lib/exec.js +++ b/lib/exec.js @@ -24,7 +24,7 @@ const BaseCommand = require('./base-command.js') // // npm x -p pkg@version -- foo --registry=/dev/null // -// const pkg = npm.flatOptions.package || getPackageFrom(args[0]) +// const pkg = npm.config.get('package') || getPackageFrom(args[0]) // const cmd = getCommand(pkg, args[0]) // --> npm x -c 'cmd ...args.slice(1)' // @@ -66,7 +66,10 @@ class Exec extends BaseCommand { // When commands go async and we can dump the boilerplate exec methods this // can be named correctly async _exec (args) { - const { package: packages, call, shell } = this.npm.flatOptions + const call = this.npm.config.get('call') + const shell = this.npm.config.get('shell') + // dereferenced because we manipulate it later + const packages = [...this.npm.config.get('package')] if (call && args.length) throw this.usage @@ -165,9 +168,9 @@ class Exec extends BaseCommand { // no need to install if already present if (add.length) { - if (!this.npm.flatOptions.yes) { + if (!this.npm.config.get('yes')) { // set -n to always say no - if (this.npm.flatOptions.yes === false) + if (this.npm.config.get('yes') === false) throw 'canceled' if (!process.stdin.isTTY || ciDetect()) { diff --git a/lib/fund.js b/lib/fund.js index a723c62d2..a4986f3c4 100644 --- a/lib/fund.js +++ b/lib/fund.js @@ -42,9 +42,8 @@ class Fund extends BaseCommand { } async fund (args) { - const opts = this.npm.flatOptions const spec = args[0] - const numberArg = opts.which + const numberArg = this.npm.config.get('which') const fundingSourceNumber = numberArg && parseInt(numberArg, 10) @@ -58,14 +57,14 @@ class Fund extends BaseCommand { throw err } - if (opts.global) { + if (this.npm.config.get('global')) { const err = new Error('`npm fund` does not support global packages') err.code = 'EFUNDGLOBAL' throw err } const where = this.npm.prefix - const arb = new Arborist({ ...opts, path: where }) + const arb = new Arborist({ ...this.npm.flatOptions, path: where }) const tree = await arb.loadActual() if (spec) { @@ -78,23 +77,19 @@ class Fund extends BaseCommand { return } - const print = opts.json - ? this.printJSON - : this.printHuman - - this.npm.output( - print( - getFundingInfo(tree), - opts - ) - ) + if (this.npm.config.get('json')) + this.npm.output(this.printJSON(getFundingInfo(tree))) + else + this.npm.output(this.printHuman(getFundingInfo(tree))) } printJSON (fundingInfo) { return JSON.stringify(fundingInfo, null, 2) } - printHuman (fundingInfo, { color, unicode }) { + printHuman (fundingInfo) { + const color = !!this.npm.color + const unicode = this.npm.config.get('unicode') const seenUrls = new Map() const tree = obj => diff --git a/lib/help-search.js b/lib/help-search.js index 4e727c3e7..62e1adb59 100644 --- a/lib/help-search.js +++ b/lib/help-search.js @@ -166,7 +166,7 @@ class HelpSearch extends BaseCommand { out.push(' '.repeat((Math.max(1, cols - out.join(' ').length - r.length - 1)))) out.push(r) - if (!this.npm.flatOptions.long) + if (!this.npm.config.get('long')) return out.join('') out.unshift('\n\n') @@ -198,7 +198,7 @@ class HelpSearch extends BaseCommand { return out.join('') }).join('\n') - const finalOut = results.length && !this.npm.flatOptions.long + const finalOut = results.length && !this.npm.config.get('long') ? 'Top hits for ' + (args.map(JSON.stringify).join(' ')) + '\n' + '—'.repeat(cols - 1) + '\n' + out + '\n' + diff --git a/lib/init.js b/lib/init.js index 42b02dfdc..3d11050e4 100644 --- a/lib/init.js +++ b/lib/init.js @@ -59,7 +59,7 @@ class Init extends BaseCommand { this.npm.log.pause() this.npm.log.disableProgress() const initFile = this.npm.config.get('init-module') - if (!this.npm.flatOptions.yes && !this.npm.flatOptions.force) { + if (!this.npm.config.get('yes') && !this.npm.config.get('force')) { this.npm.output([ 'This utility will walk you through creating a package.json file.', 'It only covers the most common items, and tries to guess sensible defaults.', diff --git a/lib/install.js b/lib/install.js index 8df63a219..34d0b2353 100644 --- a/lib/install.js +++ b/lib/install.js @@ -98,7 +98,8 @@ class Install extends BaseCommand { async install (args) { // the /path/to/node_modules/.. const globalTop = resolve(this.npm.globalDir, '..') - const { ignoreScripts, global: isGlobalInstall } = this.npm.flatOptions + const ignoreScripts = this.npm.config.get('ignore-scripts') + const isGlobalInstall = this.npm.config.get('global') const where = isGlobalInstall ? globalTop : this.npm.prefix // don't try to install the prefix into itself @@ -122,7 +123,7 @@ class Install extends BaseCommand { add: args, }) if (!args.length && !isGlobalInstall && !ignoreScripts) { - const { scriptShell } = this.npm.flatOptions + const scriptShell = this.npm.config.get('script-shell') || undefined const scripts = [ 'preinstall', 'install', diff --git a/lib/link.js b/lib/link.js index 66f83d9f5..9aad6dc1d 100644 --- a/lib/link.js +++ b/lib/link.js @@ -96,7 +96,13 @@ class Link extends BaseCommand { // npm link should not save=true by default unless you're // using any of --save-dev or other types const save = - Boolean(this.npm.config.find('save') !== 'default' || this.npm.flatOptions.saveType) + Boolean( + this.npm.config.find('save') !== 'default' || + this.npm.config.get('save-optional') || + this.npm.config.get('save-peer') || + this.npm.config.get('save-dev') || + this.npm.config.get('save-prod') + ) // create a new arborist instance for the local prefix and // reify all the pending names as symlinks there diff --git a/lib/logout.js b/lib/logout.js index b3f64f671..3784020ec 100644 --- a/lib/logout.js +++ b/lib/logout.js @@ -19,9 +19,10 @@ class Logout extends BaseCommand { } async logout (args) { - const { registry, scope } = this.npm.flatOptions + const registry = this.npm.config.get('registry') + const scope = this.npm.config.get('scope') const regRef = scope ? `${scope}:registry` : 'registry' - const reg = this.npm.flatOptions[regRef] || registry + const reg = this.npm.config.get(regRef) || registry const auth = getAuth(reg, this.npm.flatOptions) @@ -43,24 +43,22 @@ class LS extends BaseCommand { } async ls (args) { - const { - all, - color, - depth, - json, - long, - global, - parseable, - prefix, - unicode, - } = this.npm.flatOptions - const path = global ? resolve(this.npm.globalDir, '..') : prefix + const all = this.npm.config.get('all') + const color = !!this.npm.color + const depth = this.npm.config.get('depth') const dev = this.npm.config.get('dev') const development = this.npm.config.get('development') + const global = this.npm.config.get('global') + const json = this.npm.config.get('json') const link = this.npm.config.get('link') + const long = this.npm.config.get('long') const only = this.npm.config.get('only') + const parseable = this.npm.config.get('parseable') const prod = this.npm.config.get('prod') const production = this.npm.config.get('production') + const unicode = this.npm.config.get('unicode') + + const path = global ? resolve(this.npm.globalDir, '..') : this.npm.prefix const arb = new Arborist({ global, diff --git a/lib/outdated.js b/lib/outdated.js index 7225577ea..6a7b4e7b3 100644 --- a/lib/outdated.js +++ b/lib/outdated.js @@ -28,15 +28,13 @@ class Outdated extends BaseCommand { } async outdated (args) { - this.opts = this.npm.flatOptions - const global = path.resolve(this.npm.globalDir, '..') - const where = this.opts.global + const where = this.npm.config.get('global') ? global : this.npm.prefix const arb = new Arborist({ - ...this.opts, + ...this.npm.flatOptions, path: where, }) @@ -51,7 +49,7 @@ class Outdated extends BaseCommand { this.getEdges(nodes, 'edgesIn') } } else { - if (this.opts.all) { + if (this.npm.config.get('all')) { // all deps in tree const nodes = this.tree.inventory.values() this.getEdges(nodes, 'edgesOut') @@ -68,13 +66,13 @@ class Outdated extends BaseCommand { const outdated = this.list.sort((a, b) => a.name.localeCompare(b.name)) // return if no outdated packages - if (outdated.length === 0 && !this.opts.json) + if (outdated.length === 0 && !this.npm.config.get('json')) return // display results - if (this.opts.json) + if (this.npm.config.get('json')) this.npm.output(this.makeJSON(outdated)) - else if (this.opts.parseable) + else if (this.npm.config.get('parseable')) this.npm.output(this.makeParseable(outdated)) else { const outList = outdated.map(x => this.makePretty(x)) @@ -86,11 +84,11 @@ class Outdated extends BaseCommand { 'Depended by', ] - if (this.opts.long) + if (this.npm.config.get('long')) outHead.push('Package Type', 'Homepage') const outTable = [outHead].concat(outList) - if (this.opts.color) + if (this.npm.color) outTable[0] = outTable[0].map(heading => styles.underline(heading)) const tableOpts = { @@ -117,7 +115,7 @@ class Outdated extends BaseCommand { } getEdgesOut (node) { - if (this.opts.global) { + if (this.npm.config.get('global')) { for (const child of node.children.values()) this.edges.add(child) } else { @@ -129,7 +127,7 @@ class Outdated extends BaseCommand { async getPackument (spec) { const packument = await pacote.packument(spec, { ...this.npm.flatOptions, - fullMetadata: this.npm.flatOptions.long, + fullMetadata: this.npm.config.get('long'), preferOnline: true, }) return packument @@ -146,7 +144,7 @@ class Outdated extends BaseCommand { : edge.dev ? 'devDependencies' : 'dependencies' - for (const omitType of this.opts.omit || []) { + for (const omitType of this.npm.config.get('omit') || []) { if (node[omitType]) return } @@ -213,12 +211,12 @@ class Outdated extends BaseCommand { const columns = [name, current, wanted, latest, location, dependent] - if (this.opts.long) { + if (this.npm.config.get('long')) { columns[6] = type columns[7] = homepage } - if (this.opts.color) { + if (this.npm.color) { columns[0] = color[current === wanted ? 'yellow' : 'red'](columns[0]) // current columns[2] = color.green(columns[2]) // wanted columns[3] = color.magenta(columns[3]) // latest @@ -248,7 +246,7 @@ class Outdated extends BaseCommand { name + '@' + latest, dependent, ] - if (this.opts.long) + if (this.npm.config.get('long')) out.push(type, homepage) return out.join(':') @@ -275,7 +273,7 @@ class Outdated extends BaseCommand { dependent, location: path, } - if (this.opts.long) { + if (this.npm.config.get('long')) { out[name].type = type out[name].homepage = homepage } diff --git a/lib/pack.js b/lib/pack.js index 326fcc0cd..cdd823430 100644 --- a/lib/pack.js +++ b/lib/pack.js @@ -29,12 +29,12 @@ class Pack extends BaseCommand { if (args.length === 0) args = ['.'] - const { unicode } = this.npm.flatOptions + const unicode = this.npm.config.get('unicode') // clone the opts because pacote mutates it with resolved/integrity const tarballs = await Promise.all(args.map(async (arg) => { const spec = npa(arg) - const { dryRun } = this.npm.flatOptions + const dryRun = this.npm.config.get('dry-run') const manifest = await pacote.manifest(spec, this.npm.flatOptions) const filename = `${manifest.name}-${manifest.version}.tgz` .replace(/^@/, '').replace(/\//, '-') diff --git a/lib/ping.js b/lib/ping.js index e60b1f1de..53467c93b 100644 --- a/lib/ping.js +++ b/lib/ping.js @@ -18,14 +18,14 @@ class Ping extends BaseCommand { } async ping (args) { - log.notice('PING', this.npm.flatOptions.registry) + log.notice('PING', this.npm.config.get('registry')) const start = Date.now() const details = await pingUtil(this.npm.flatOptions) const time = Date.now() - start log.notice('PONG', `${time / 1000}ms`) - if (this.npm.flatOptions.json) { + if (this.npm.config.get('json')) { this.npm.output(JSON.stringify({ - registry: this.npm.flatOptions.registry, + registry: this.npm.config.get('registry'), time, details, }, null, 2)) diff --git a/lib/profile.js b/lib/profile.js index 1c0df4988..3d4857df0 100644 --- a/lib/profile.js +++ b/lib/profile.js @@ -108,14 +108,14 @@ class Profile extends BaseCommand { async get (args) { const tfa = 'two-factor auth' - const conf = { ...this.npm.flatOptions } - - const info = await pulseTillDone.withPromise(npmProfile.get(conf)) + const info = await pulseTillDone.withPromise( + npmProfile.get(this.npm.flatOptions) + ) if (!info.cidr_whitelist) delete info.cidr_whitelist - if (conf.json) { + if (this.npm.config.get('json')) { this.npm.output(JSON.stringify(info, null, 2)) return } @@ -147,7 +147,7 @@ class Profile extends BaseCommand { .join('\t') this.npm.output(values) } else { - if (conf.parseable) { + if (this.npm.config.get('parseable')) { for (const key of Object.keys(info)) { if (key === 'tfa') this.npm.output(`${key}\t${cleaned[tfa]}`) @@ -165,7 +165,7 @@ class Profile extends BaseCommand { } async set (args) { - const conf = { ...this.npm.flatOptions } + const conf = this.npm.flatOptions const prop = (args[0] || '').toLowerCase().trim() let value = args.length > 1 ? args.slice(1).join(' ') : null @@ -214,9 +214,9 @@ class Profile extends BaseCommand { const result = await otplease(conf, conf => npmProfile.set(newUser, conf)) - if (conf.json) + if (this.npm.config.get('json')) this.npm.output(JSON.stringify({ [prop]: result[prop] }, null, 2)) - else if (conf.parseable) + else if (this.npm.config.get('parseable')) this.npm.output(prop + '\t' + result[prop]) else if (result[prop] != null) this.npm.output('Set', prop, 'to', result[prop]) @@ -239,11 +239,10 @@ class Profile extends BaseCommand { ) } - const conf = { ...this.npm.flatOptions } - if (conf.json || conf.parseable) { + if (this.npm.config.get('json') || this.npm.config.get('parseable')) { throw new Error( 'Enabling two-factor authentication is an interactive operation and ' + - (conf.json ? 'JSON' : 'parseable') + ' output mode is not available' + (this.npm.config.get('json') ? 'JSON' : 'parseable') + ' output mode is not available' ) } @@ -255,7 +254,7 @@ class Profile extends BaseCommand { // if they're using legacy auth currently then we have to // update them to a bearer token before continuing. - const creds = this.npm.config.getCredentialsByURI(conf.registry) + const creds = this.npm.config.getCredentialsByURI(this.npm.config.get('registry')) const auth = {} if (creds.token) @@ -267,32 +266,29 @@ class Profile extends BaseCommand { auth.basic = { username: basic[0], password: basic[1] } } - if (conf.otp) - auth.otp = conf.otp - if (!auth.basic && !auth.token) { throw new Error( 'You need to be logged in to registry ' + - `${conf.registry} in order to enable 2fa` + `${this.npm.config.get('registry')} in order to enable 2fa` ) } if (auth.basic) { log.info('profile', 'Updating authentication to bearer token') const result = await npmProfile.createToken( - auth.basic.password, false, [], conf + auth.basic.password, false, [], this.npm.flatOptions ) if (!result.token) { throw new Error( - `Your registry ${conf.registry} does not seem to ` + + `Your registry ${this.npm.config.get('registry')} does not seem to ` + 'support bearer tokens. Bearer tokens are required for ' + 'two-factor authentication' ) } this.npm.config.setCredentialsByURI( - conf.registry, + this.npm.config.get('registry'), { token: result.token } ) await this.npm.config.save('user') @@ -303,21 +299,21 @@ class Profile extends BaseCommand { info.tfa.password = password log.info('profile', 'Determine if tfa is pending') - const userInfo = await pulseTillDone.withPromise(npmProfile.get(conf)) + const userInfo = await pulseTillDone.withPromise( + npmProfile.get(this.npm.flatOptions) + ) + const conf = { ...this.npm.flatOptions } if (userInfo && userInfo.tfa && userInfo.tfa.pending) { log.info('profile', 'Resetting two-factor authentication') await pulseTillDone.withPromise( npmProfile.set({ tfa: { password, mode: 'disable' } }, conf) ) } else if (userInfo && userInfo.tfa) { - if (conf.otp) - conf.otp = conf.otp - else { - const otp = await readUserInfo.otp( + if (!conf.otp) { + conf.otp = await readUserInfo.otp( 'Enter one-time password from your authenticator app: ' ) - conf.otp = otp } } @@ -390,9 +386,9 @@ class Profile extends BaseCommand { tfa: { password: password, mode: 'disable' }, }, conf)) - if (conf.json) + if (this.npm.config.get('json')) this.npm.output(JSON.stringify({ tfa: false }, null, 2)) - else if (conf.parseable) + else if (this.npm.config.get('parseable')) this.npm.output('tfa\tfalse') else this.npm.output('Two factor authentication disabled.') diff --git a/lib/publish.js b/lib/publish.js index f8e0eafe1..f46f70291 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -43,12 +43,16 @@ class Publish extends BaseCommand { log.verbose('publish', args) - const opts = { ...this.npm.flatOptions } - const { unicode, dryRun, json, defaultTag } = opts + const unicode = this.npm.config.get('unicode') + const dryRun = this.npm.config.get('dry-run') + const json = this.npm.config.get('json') + const defaultTag = this.npm.config.get('tag') if (semver.validRange(defaultTag)) throw new Error('Tag name must not be a valid SemVer range: ' + defaultTag.trim()) + const opts = { ...this.npm.flatOptions } + // you can publish name@version, ./foo.tgz, etc. // even though the default is the 'file:.' cwd. const spec = npa(args[0]) diff --git a/lib/rebuild.js b/lib/rebuild.js index 74f5ae5f6..c11747b97 100644 --- a/lib/rebuild.js +++ b/lib/rebuild.js @@ -27,7 +27,7 @@ class Rebuild extends BaseCommand { async rebuild (args) { const globalTop = resolve(this.npm.globalDir, '..') - const where = this.npm.flatOptions.global ? globalTop : this.npm.prefix + const where = this.npm.config.get('global') ? globalTop : this.npm.prefix const arb = new Arborist({ ...this.npm.flatOptions, path: where, diff --git a/lib/run-script.js b/lib/run-script.js index 3ea85b79f..f6ca57b79 100644 --- a/lib/run-script.js +++ b/lib/run-script.js @@ -49,7 +49,9 @@ class RunScript extends BaseCommand { async run (args) { const path = this.npm.localPrefix const event = args.shift() - const { scriptShell } = this.npm.flatOptions + // this || undefined is because runScript will be unhappy with the default + // null value + const scriptShell = this.npm.config.get('script-shell') || undefined const pkg = await readJson(`${path}/package.json`) const { scripts = {} } = pkg @@ -75,7 +77,7 @@ class RunScript extends BaseCommand { // positional args only added to the main event, not pre/post const events = [[event, args]] - if (!this.npm.flatOptions.ignoreScripts) { + if (!this.npm.config.get('ignore-scripts')) { if (scripts[`pre${event}`]) events.unshift([`pre${event}`, []]) @@ -113,12 +115,12 @@ class RunScript extends BaseCommand { if (log.level === 'silent') return allScripts - if (this.npm.flatOptions.json) { + if (this.npm.config.get('json')) { this.npm.output(JSON.stringify(scripts, null, 2)) return allScripts } - if (this.npm.flatOptions.parseable) { + if (this.npm.config.get('parseable')) { for (const [script, cmd] of Object.entries(scripts)) this.npm.output(`${script}:${cmd}`) diff --git a/lib/search.js b/lib/search.js index c24000156..4c206498f 100644 --- a/lib/search.js +++ b/lib/search.js @@ -84,7 +84,7 @@ class Search extends BaseCommand { }) await p.promise() - if (!anyOutput && !opts.json && !opts.parseable) + if (!anyOutput && !this.npm.config.get('json') && !this.npm.config.get('parseable')) this.npm.output('No matches found for ' + (args.map(JSON.stringify).join(' '))) log.silly('search', 'search completed') diff --git a/lib/shrinkwrap.js b/lib/shrinkwrap.js index b52cf4195..76979b021 100644 --- a/lib/shrinkwrap.js +++ b/lib/shrinkwrap.js @@ -24,7 +24,7 @@ class Shrinkwrap extends BaseCommand { // // loadVirtual, fall back to loadActual // rename shrinkwrap file type, and tree.meta.save() - if (this.npm.flatOptions.global) { + if (this.npm.config.get('global')) { const er = new Error('`npm shrinkwrap` does not work for global packages') er.code = 'ESHRINKWRAPGLOBAL' throw er diff --git a/lib/star.js b/lib/star.js index 27a304190..9a8ee8c77 100644 --- a/lib/star.js +++ b/lib/star.js @@ -26,7 +26,7 @@ class Star extends BaseCommand { // if we're unstarring, then show an empty star image // otherwise, show the full star image - const { unicode } = this.npm.flatOptions + const unicode = this.npm.config.get('unicode') const unstar = this.npm.config.get('star.unstar') const full = unicode ? '\u2605 ' : '(*)' const empty = unicode ? '\u2606 ' : '( )' diff --git a/lib/uninstall.js b/lib/uninstall.js index ee0f338e9..c1c36ab6b 100644 --- a/lib/uninstall.js +++ b/lib/uninstall.js @@ -28,7 +28,8 @@ class Uninstall extends BaseCommand { async uninstall (args) { // the /path/to/node_modules/.. - const { global, prefix } = this.npm.flatOptions + const global = this.npm.config.get('global') + const prefix = this.npm.config.get('prefix') const path = global ? resolve(this.npm.globalDir, '..') : prefix if (!args.length) { diff --git a/lib/unpublish.js b/lib/unpublish.js index 68a9a0ae6..06b2779b2 100644 --- a/lib/unpublish.js +++ b/lib/unpublish.js @@ -63,8 +63,9 @@ class Unpublish extends BaseCommand { throw new Error(this.usage) const spec = args.length && npa(args[0]) - const opts = this.npm.flatOptions - const { force, silent, loglevel } = opts + const force = this.npm.config.get('force') + const silent = this.npm.config.get('silent') + const loglevel = this.npm.config.get('loglevel') let pkgName let pkgVersion @@ -79,6 +80,7 @@ class Unpublish extends BaseCommand { ) } + const opts = this.npm.flatOptions if (!spec || path.resolve(spec.name) === this.npm.localPrefix) { // if there's a package.json in the current folder, then // read the package name and version out of that. diff --git a/lib/update.js b/lib/update.js index 87540b96e..8ce52a442 100644 --- a/lib/update.js +++ b/lib/update.js @@ -30,11 +30,11 @@ class Update extends BaseCommand { async update (args) { const update = args.length === 0 ? true : args const global = path.resolve(this.npm.globalDir, '..') - const where = this.npm.flatOptions.global + const where = this.npm.config.get('global') ? global : this.npm.prefix - if (this.npm.flatOptions.depth) { + if (this.npm.config.get('depth')) { log.warn('update', 'The --depth option no longer has any effect. See RFC0019.\n' + 'https://github.com/npm/rfcs/blob/latest/implemented/0019-remove-update-depth-option.md') } diff --git a/lib/utils/ping.js b/lib/utils/ping.js index f5f7fcc6a..00956d0c1 100644 --- a/lib/utils/ping.js +++ b/lib/utils/ping.js @@ -1,7 +1,7 @@ // ping the npm registry // used by the ping and doctor commands const fetch = require('npm-registry-fetch') -module.exports = async (opts) => { - const res = await fetch('/-/ping?write=true', opts) +module.exports = async (flatOptions) => { + const res = await fetch('/-/ping?write=true', flatOptions) return res.json().catch(() => ({})) } diff --git a/lib/utils/read-local-package.js b/lib/utils/read-local-package.js index c31bca994..21506ca18 100644 --- a/lib/utils/read-local-package.js +++ b/lib/utils/read-local-package.js @@ -1,11 +1,12 @@ const { resolve } = require('path') const readJson = require('read-package-json-fast') async function readLocalPackageName (npm) { - if (npm.flatOptions.global) + if (npm.config.get('global')) return - const filepath = resolve(npm.flatOptions.prefix, 'package.json') - return (await readJson(filepath)).name + const filepath = resolve(npm.prefix, 'package.json') + const json = await readJson(filepath) + return json.name } module.exports = readLocalPackageName diff --git a/lib/version.js b/lib/version.js index 2eda9d11b..30097a3c3 100644 --- a/lib/version.js +++ b/lib/version.js @@ -45,7 +45,7 @@ class Version extends BaseCommand { } async change (args) { - const prefix = this.npm.flatOptions.tagVersionPrefix + const prefix = this.npm.config.get('tag-version-prefix') const version = await libversion(args[0], { ...this.npm.flatOptions, path: this.npm.prefix, @@ -71,7 +71,7 @@ class Version extends BaseCommand { for (const [key, version] of Object.entries(process.versions)) results[key] = version - if (this.npm.flatOptions.json) + if (this.npm.config.get('json')) this.npm.output(JSON.stringify(results, null, 2)) else this.npm.output(results) diff --git a/lib/view.js b/lib/view.js index 0a6688fc2..7bbedcf65 100644 --- a/lib/view.js +++ b/lib/view.js @@ -41,9 +41,9 @@ class View extends BaseCommand { fullMetadata: true, preferOnline: true, } - const { defaultTag } = config const spec = npa(opts.conf.argv.remain[2]) const pckmnt = await packument(spec, config) + const defaultTag = this.npm.config.get('tag') const dv = pckmnt.versions[pckmnt['dist-tags'][defaultTag]] pckmnt.versions = Object.keys(pckmnt.versions).sort(semver.compareLoose) @@ -99,7 +99,7 @@ class View extends BaseCommand { const name = nv.name const local = (name === '.' || !name) - if (opts.global && local) + if (this.npm.config.get('global') && local) throw new Error('Cannot use view command in global mode.') if (local) { @@ -114,7 +114,7 @@ class View extends BaseCommand { } // get the data about this package - let version = nv.rawSpec || this.npm.flatOptions.defaultTag + let version = nv.rawSpec || this.npm.config.get('tag') const pckmnt = await packument(nv, opts) @@ -159,42 +159,43 @@ class View extends BaseCommand { } if ( - !opts.json && + !this.npm.config.get('json') && args.length === 1 && args[0] === '' ) { // general view pckmnt.version = version await Promise.all( - results.map((v) => this.prettyView(pckmnt, v[Object.keys(v)[0]][''], opts)) + results.map((v) => this.prettyView(pckmnt, v[Object.keys(v)[0]][''])) ) return retval } else { // view by field name - await this.printData(retval, pckmnt._id, opts) + await this.printData(retval, pckmnt._id) return retval } } - async printData (data, name, opts) { + async printData (data, name) { const versions = Object.keys(data) let msg = '' let msgJson = [] const includeVersions = versions.length > 1 let includeFields + const json = this.npm.config.get('json') versions.forEach((v) => { const fields = Object.keys(data[v]) includeFields = includeFields || (fields.length > 1) - if (opts.json) + if (json) msgJson.push({}) fields.forEach((f) => { let d = cleanup(data[v][f]) - if (fields.length === 1 && opts.json) + if (fields.length === 1 && json) msgJson[msgJson.length - 1][f] = d if (includeVersions || includeFields || typeof d !== 'string') { - if (opts.json) + if (json) msgJson[msgJson.length - 1][f] = d else { d = inspect(d, { @@ -204,10 +205,10 @@ class View extends BaseCommand { maxArrayLength: null, }) } - } else if (typeof d === 'string' && opts.json) + } else if (typeof d === 'string' && json) d = JSON.stringify(d) - if (!opts.json) { + if (!json) { if (f && includeFields) f += ' = ' msg += (includeVersions ? name + '@' + v + ' ' : '') + @@ -216,7 +217,7 @@ class View extends BaseCommand { }) }) - if (opts.json) { + if (json) { if (msgJson.length && Object.keys(msgJson[0]).length === 1) { const k = Object.keys(msgJson[0])[0] msgJson = msgJson.map(m => m[k]) @@ -236,9 +237,9 @@ class View extends BaseCommand { console.log(msg.trim()) } - async prettyView (packument, manifest, opts) { + async prettyView (packument, manifest) { // More modern, pretty printing of default view - const unicode = opts.unicode + const unicode = this.npm.config.get('unicode') const tags = [] Object.keys(packument['dist-tags']).forEach((t) => { diff --git a/lib/whoami.js b/lib/whoami.js index 2322c5fd8..180eb3317 100644 --- a/lib/whoami.js +++ b/lib/whoami.js @@ -22,9 +22,10 @@ class Whoami extends BaseCommand { } async whoami (args) { - const opts = this.npm.flatOptions - const username = await getIdentity(this.npm, opts) - this.npm.output(opts.json ? JSON.stringify(username) : username) + const username = await getIdentity(this.npm, this.npm.flatOptions) + this.npm.output( + this.npm.config.get('json') ? JSON.stringify(username) : username + ) } } module.exports = Whoami diff --git a/test/fixtures/mock-npm.js b/test/fixtures/mock-npm.js new file mode 100644 index 000000000..c47758111 --- /dev/null +++ b/test/fixtures/mock-npm.js @@ -0,0 +1,22 @@ +// Basic npm fixture that you can give a config object that acts like +// npm.config You still need a separate flatOptions but this is the first step +// to eventually just using npm itself + +const mockNpm = (base = {}) => { + const config = base.config || {} + const flatOptions = base.flatOptions || {} + return { + ...base, + flatOptions, + config: { + // for now just set `find` to what config.find should return + // this works cause `find` is not an existing config entry + find: (k) => config[k], + get: (k) => config[k], + set: (k, v) => config[k] = v, + list: [config] + }, + } +} + +module.exports = mockNpm diff --git a/test/lib/audit.js b/test/lib/audit.js index d291ef879..a25e6b0e2 100644 --- a/test/lib/audit.js +++ b/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/test/lib/bin.js b/test/lib/bin.js index 428b2e3ba..1d9341169 100644 --- a/test/lib/bin.js +++ b/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/test/lib/cache.js b/test/lib/cache.js index 773adc6a8..0fdf76856 100644 --- a/test/lib/cache.js +++ b/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/test/lib/ci.js b/test/lib/ci.js index 3419218ef..7f06a6ceb 100644 --- a/test/lib/ci.js +++ b/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/test/lib/dedupe.js b/test/lib/dedupe.js index 3e8b2f4c0..851163f93 100644 --- a/test/lib/dedupe.js +++ b/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/test/lib/diff.js b/test/lib/diff.js index 9f58505dc..08761c64c 100644 --- a/test/lib/diff.js +++ b/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/test/lib/dist-tag.js b/test/lib/dist-tag.js index a3c05bb2b..9415dacbe 100644 --- a/test/lib/dist-tag.js +++ b/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/test/lib/exec.js b/test/lib/exec.js index eb9fef6a6..5e859a57a 100644 --- a/test/lib/exec.js +++ b/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,11 @@ 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.package = [] + flatOptions.package = [] + config.call = '' + config.yes = true npm.localBin = 'local-bin' npm.globalBin = 'global-bin' cb() @@ -186,7 +187,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, [{ @@ -300,7 +301,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 +341,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 +381,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,7 +413,8 @@ 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 @@ -459,7 +461,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 +504,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 +554,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 +585,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 +654,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 +668,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 +685,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 +707,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 +740,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 +776,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 +809,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 +843,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 +868,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 +902,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') @@ -931,7 +933,7 @@ t.test('abort if prompt rejected', 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, []) @@ -958,8 +960,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 +991,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 +1017,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') @@ -1046,7 +1048,7 @@ t.test('abort if -n provided', 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, []) @@ -1073,8 +1075,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 diff --git a/test/lib/fund.js b/test/lib/fund.js index 2ae604a65..bd600dbf7 100644 --- a/test/lib/fund.js +++ b/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,11 +181,10 @@ const conflictingFundingPackages = { let result = '' let printUrl = '' -const _flatOptions = { +const config = { color: false, json: false, global: false, - prefix: undefined, unicode: false, which: undefined, } @@ -192,7 +192,7 @@ 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 = undefined 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 = undefined 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/test/lib/help-search.js b/test/lib/help-search.js index 6228f5ca9..cbb3947d3 100644 --- a/test/lib/help-search.js +++ b/test/lib/help-search.js @@ -2,6 +2,7 @@ const { test } = require('tap') const { join } = require('path') const requireInject = require('require-inject') const ansicolors = require('ansicolors') +const mockNpm = require('../fixtures/mock-npm') const OUTPUT = [] const output = (msg) => { @@ -10,11 +11,12 @@ const output = (msg) => { let npmHelpArgs = null let npmHelpErr = null -const npm = { +const config = { + long: false, +} +const npm = mockNpm({ color: false, - flatOptions: { - long: false, - }, + config, commands: { help: (args, cb) => { npmHelpArgs = args @@ -22,7 +24,7 @@ const npm = { }, }, output, -} +}) let npmUsageArg = null const npmUsage = (npm, arg) => { @@ -120,10 +122,10 @@ test('npm help-search single result propagates error', t => { 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 +140,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 }) diff --git a/test/lib/init.js b/test/lib/init.js index 8b9f32e15..2b212f4a1 100644 --- a/test/lib/init.js +++ b/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/test/lib/install.js b/test/lib/install.js index 8b7a96851..b44452a69 100644 --- a/test/lib/install.js +++ b/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/test/lib/link.js b/test/lib/link.js index be7af3f52..0d96ba0bc 100644 --- a/test/lib/link.js +++ b/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/test/lib/logout.js b/test/lib/logout.js index b00fa641d..bae797f96 100644 --- a/test/lib/logout.js +++ b/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/test/lib/ls.js b/test/lib/ls.js index bcbd34135..5367dec68 100644 --- a/test/lib/ls.js +++ b/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/test/lib/outdated.js b/test/lib/outdated.js index 02952971b..5aff7c37a 100644 --- a/test/lib/outdated.js +++ b/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/test/lib/pack.js b/test/lib/pack.js index ce319be76..a5163acfd 100644 --- a/test/lib/pack.js +++ b/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/test/lib/ping.js b/test/lib/ping.js index f3563036f..95361035a 100644 --- a/test/lib/ping.js +++ b/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/test/lib/profile.js b/test/lib/profile.js index d1be93b0c..5b1210615 100644 --- a/test/lib/profile.js +++ b/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/test/lib/publish.js b/test/lib/publish.js index 6337a1fcf..bfc58a4c3 100644 --- a/test/lib/publish.js +++ b/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 @@ -12,9 +13,7 @@ log.level = 'silent' // mock config const {defaults} = require('../../lib/utils/config.js') -const config = { - list: [defaults], -} +const config = defaults t.afterEach(cb => { log.level = 'silent' @@ -54,18 +53,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 +102,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 +143,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 +189,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 +235,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 +269,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 +313,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 +331,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 +351,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 +381,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 +418,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,15 +457,14 @@ t.test('read registry only from publishConfig', t => { }, }, }) - const publish = new Publish({ - config: { - ...config, - getCredentialsByURI: (uri) => { - t.same(uri, registry, 'gets credentials for expected registry') - return { token: 'some.registry.token' } - }, - }, + 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) diff --git a/test/lib/rebuild.js b/test/lib/rebuild.js index 1eb45e0d1..73344dae6 100644 --- a/test/lib/rebuild.js +++ b/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() @@ -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/test/lib/run-script.js b/test/lib/run-script.js index 0566daf23..c598ea707 100644 --- a/test/lib/run-script.js +++ b/test/lib/run-script.js @@ -1,33 +1,31 @@ const t = require('tap') const requireInject = require('require-inject') +const mockNpm = require('../fixtures/mock-npm') 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, - }, - get: k => npm.config.settings[k], - set: (k, v) => { - npm.config.settings[k] = v - }, - }, + flatOptions, + config, output: (...msg) => output.push(msg), -} +}) const output = [] t.afterEach(cb => { output.length = 0 RUN_SCRIPTS.length = 0 - npm.flatOptions.json = false - npm.flatOptions.parseable = false + config.json = false + config.parseable = false cb() }) @@ -331,7 +329,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 +366,7 @@ t.test('skip pre/post hooks when using ignoreScripts', t => { }, ]) t.end() - delete npm.flatOptions.ignoreScripts + delete config['ignore-scripts'] }) }) @@ -466,7 +464,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 +474,7 @@ t.test('list scripts', t => { }) t.test('parseable', t => { - npm.flatOptions.parseable = true + config.parseable = true runScript.exec([], er => { if (er) throw er diff --git a/test/lib/search.js b/test/lib/search.js index b1ba7775c..b7b408442 100644 --- a/test/lib/search.js +++ b/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/test/lib/shrinkwrap.js b/test/lib/shrinkwrap.js index dc4bc3b22..b3de4f5fa 100644 --- a/test/lib/shrinkwrap.js +++ b/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, @@ -36,7 +41,7 @@ const mocks = { t.afterEach(cb => { npm.prefix = '' - npm.flatOptions.global = false + config.global = false npm.globalDir = '' cb() }) @@ -50,7 +55,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 +106,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 +161,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 +223,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 +277,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 +325,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/test/lib/star.js b/test/lib/star.js index 774fabe39..fa75d2105 100644 --- a/test/lib/star.js +++ b/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/test/lib/uninstall.js b/test/lib/uninstall.js index c62b59950..5cb8a243e 100644 --- a/test/lib/uninstall.js +++ b/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/test/lib/unpublish.js b/test/lib/unpublish.js index b1255b94a..ba99b5330 100644 --- a/test/lib/unpublish.js +++ b/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/test/lib/update.js b/test/lib/update.js index 15195573f..695218a7f 100644 --- a/test/lib/update.js +++ b/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/test/lib/utils/read-local-package.js b/test/lib/utils/read-local-package.js index 9ae21f7d6..4b693afb4 100644 --- a/test/lib/utils/read-local-package.js +++ b/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/test/lib/version.js b/test/lib/version.js index a8fcd831f..35d3d92cd 100644 --- a/test/lib/version.js +++ b/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/test/lib/view.js b/test/lib/view.js index 1363a5b9f..d136a1f41 100644 --- a/test/lib/view.js +++ b/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/test/lib/whoami.js b/test/lib/whoami.js index 1a1ecd257..b242ea894 100644 --- a/test/lib/whoami.js +++ b/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') |