Skip to content

Commit

Permalink
fix(libnpmexec): don't detach output from npm
Browse files Browse the repository at this point in the history
The npm output function refers to this.log.  libnpmexec has that passed
in, which decoupled the function from the npm object.  This fixes it,
and sets the tests up in a way where if the output function ever becomes
detached from this.npm in the same way, tests will fail.
  • Loading branch information
wraithgar committed May 28, 2021
1 parent 685f4be commit 996248c
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 48 deletions.
2 changes: 1 addition & 1 deletion lib/exec.js
Expand Up @@ -76,8 +76,8 @@ class Exec extends BaseCommand {
localBin,
log,
globalBin,
output,
} = this.npm
const output = (...outputArgs) => this.npm.output(...outputArgs)
const scriptShell = this.npm.config.get('script-shell') || undefined
const packages = this.npm.config.get('package')
const yes = this.npm.config.get('yes')
Expand Down
2 changes: 1 addition & 1 deletion lib/init.js
Expand Up @@ -113,8 +113,8 @@ class Init extends BaseCommand {
localBin,
log,
globalBin,
output,
} = this.npm
const output = (...outputArgs) => this.npm.output(...outputArgs)
const locationMsg = await getLocationMsg({ color, path })
const runPath = path
const scriptShell = this.npm.config.get('script-shell') || undefined
Expand Down
6 changes: 3 additions & 3 deletions tap-snapshots/test/lib/init.js.test.cjs
Expand Up @@ -6,13 +6,13 @@
*/
'use strict'
exports[`test/lib/init.js TAP workspaces no args > should print helper info 1`] = `
Array []
`

exports[`test/lib/init.js TAP workspaces no args, existing folder > should print helper info 1`] = `
Array []
`

exports[`test/lib/init.js TAP workspaces with arg but missing workspace folder > should print helper info 1`] = `
Array []
`
65 changes: 42 additions & 23 deletions test/fixtures/mock-npm.js
Expand Up @@ -4,35 +4,54 @@

const realConfig = require('../../lib/utils/config')

const mockLog = {
clearProgress: () => {},
disableProgress: () => {},
enableProgress: () => {},
http: () => {},
info: () => {},
levels: [],
notice: () => {},
pause: () => {},
silly: () => {},
verbose: () => {},
warn: () => {},
}
const mockNpm = (base = {}) => {
const config = base.config || {}
const flatOptions = base.flatOptions || {}
return {
log: mockLog,
...base,
flatOptions,
config: {
class MockNpm {
constructor (base = {}) {
this._mockOutputs = []
this.isMockNpm = true
this.base = base

const config = base.config || {}

for (const attr in base) {
if (attr !== 'config') {
this[attr] = base[attr]
}
}

this.flatOptions = base.flatOptions || {}
this.config = {
// for now just set `find` to what config.find should return
// this works cause `find` is not an existing config entry
find: (k) => ({...realConfig.defaults, ...config})[k],
get: (k) => ({...realConfig.defaults, ...config})[k],
set: (k, v) => config[k] = v,
list: [{ ...realConfig.defaults, ...config}]
},
}
if (!this.log) {
this.log = {
clearProgress: () => {},
disableProgress: () => {},
enableProgress: () => {},
http: () => {},
info: () => {},
levels: [],
notice: () => {},
pause: () => {},
silly: () => {},
verbose: () => {},
warn: () => {},
}
}
}

output(...msg) {
if (this.base.output)
return this.base.output(msg)
this._mockOutputs.push(msg)
}
}

module.exports = mockNpm
// TODO export MockNpm, and change tests to use new MockNpm()
module.exports = (base = {}) => {
return new MockNpm(base)
}
22 changes: 10 additions & 12 deletions test/lib/exec.js
@@ -1,8 +1,6 @@
const t = require('tap')
const mockNpm = require('../fixtures/mock-npm')
const { resolve, delimiter } = require('path')
const OUTPUT = []
const output = (...msg) => OUTPUT.push(msg)

const ARB_CTOR = []
const ARB_ACTUAL_TREE = {}
Expand Down Expand Up @@ -36,6 +34,7 @@ const config = {
package: [],
'script-shell': 'shell-cmd',
}

const npm = mockNpm({
flatOptions,
config,
Expand All @@ -53,7 +52,6 @@ const npm = mockNpm({
LOG_WARN.push(args)
},
},
output,
})

const RUN_SCRIPTS = []
Expand Down Expand Up @@ -225,7 +223,7 @@ t.test('npm exec <noargs>, run interactive shell', t => {
ARB_CTOR.length = 0
MKDIRPS.length = 0
ARB_REIFY.length = 0
OUTPUT.length = 0
npm._mockOutputs.length = 0
exec.exec([], er => {
if (er)
throw er
Expand Down Expand Up @@ -256,7 +254,7 @@ t.test('npm exec <noargs>, run interactive shell', t => {
process.stdin.isTTY = true
run(t, true, () => {
t.strictSame(LOG_WARN, [])
t.strictSame(OUTPUT, [
t.strictSame(npm._mockOutputs, [
[`\nEntering npm script environment at location:\n${process.cwd()}\nType 'exit' or ^D when finished\n`],
], 'printed message about interactive shell')
t.end()
Expand All @@ -270,7 +268,7 @@ t.test('npm exec <noargs>, run interactive shell', t => {

run(t, true, () => {
t.strictSame(LOG_WARN, [])
t.strictSame(OUTPUT, [
t.strictSame(npm._mockOutputs, [
[`\u001b[0m\u001b[0m\n\u001b[0mEntering npm script environment\u001b[0m\u001b[0m at location:\u001b[0m\n\u001b[0m\u001b[2m${process.cwd()}\u001b[22m\u001b[0m\u001b[1m\u001b[22m\n\u001b[1mType 'exit' or ^D when finished\u001b[22m\n\u001b[1m\u001b[22m`],
], 'printed message about interactive shell')
t.end()
Expand All @@ -282,7 +280,7 @@ t.test('npm exec <noargs>, run interactive shell', t => {
process.stdin.isTTY = false
run(t, true, () => {
t.strictSame(LOG_WARN, [])
t.strictSame(OUTPUT, [], 'no message about interactive shell')
t.strictSame(npm._mockOutputs, [], 'no message about interactive shell')
t.end()
})
})
Expand All @@ -294,7 +292,7 @@ t.test('npm exec <noargs>, run interactive shell', t => {
t.strictSame(LOG_WARN, [
['exec', 'Interactive mode disabled in CI environment'],
])
t.strictSame(OUTPUT, [], 'no message about interactive shell')
t.strictSame(npm._mockOutputs, [], 'no message about interactive shell')
t.end()
})
})
Expand All @@ -316,7 +314,7 @@ t.test('npm exec <noargs>, run interactive shell', t => {
ARB_CTOR.length = 0
MKDIRPS.length = 0
ARB_REIFY.length = 0
OUTPUT.length = 0
npm._mockOutputs.length = 0
RUN_SCRIPTS.length = 0
t.end()
})
Expand Down Expand Up @@ -1195,22 +1193,22 @@ t.test('workspaces', t => {
return rej(er)

t.strictSame(LOG_WARN, [])
t.strictSame(OUTPUT, [
t.strictSame(npm._mockOutputs, [
[`\nEntering npm script environment in workspace a@1.0.0 at location:\n${resolve(npm.localPrefix, 'packages/a')}\nType 'exit' or ^D when finished\n`],
], 'printed message about interactive shell')
res()
})
})

config.color = true
OUTPUT.length = 0
npm._mockOutputs.length = 0
await new Promise((res, rej) => {
exec.execWorkspaces([], ['a'], er => {
if (er)
return rej(er)

t.strictSame(LOG_WARN, [])
t.strictSame(OUTPUT, [
t.strictSame(npm._mockOutputs, [
[`\u001b[0m\u001b[0m\n\u001b[0mEntering npm script environment\u001b[0m\u001b[0m in workspace \u001b[32ma@1.0.0\u001b[39m at location:\u001b[0m\n\u001b[0m\u001b[2m${resolve(npm.localPrefix, 'packages/a')}\u001b[22m\u001b[0m\u001b[1m\u001b[22m\n\u001b[1mType 'exit' or ^D when finished\u001b[22m\n\u001b[1m\u001b[22m`],
], 'printed message about interactive shell')
res()
Expand Down
12 changes: 4 additions & 8 deletions test/lib/init.js
Expand Up @@ -3,7 +3,6 @@ const { resolve } = require('path')
const t = require('tap')
const mockNpm = require('../fixtures/mock-npm')

let result = ''
const npmLog = {
disableProgress: () => null,
enableProgress: () => null,
Expand All @@ -19,9 +18,6 @@ const config = {
const npm = mockNpm({
config,
log: npmLog,
output: (...msg) => {
result += msg.join('\n')
},
})
const mocks = {
'../../lib/utils/usage.js': () => 'usage instructions',
Expand All @@ -33,11 +29,11 @@ const _consolelog = console.log
const noop = () => {}

t.afterEach(() => {
result = ''
config.yes = true
config.package = undefined
npm.log = npmLog
process.chdir(_cwd)
npm._mockOutputs.length = 0
console.log = _consolelog
})

Expand Down Expand Up @@ -340,7 +336,7 @@ t.test('workspaces', t => {
if (err)
throw err

t.matchSnapshot(result, 'should print helper info')
t.matchSnapshot(npm._mockOutputs, 'should print helper info')
t.end()
})
})
Expand Down Expand Up @@ -369,7 +365,7 @@ t.test('workspaces', t => {
if (err)
throw err

t.matchSnapshot(result, 'should print helper info')
t.matchSnapshot(npm._mockOutputs, 'should print helper info')
t.end()
})
})
Expand Down Expand Up @@ -401,7 +397,7 @@ t.test('workspaces', t => {
if (err)
throw err

t.matchSnapshot(result, 'should print helper info')
t.matchSnapshot(npm._mockOutputs, 'should print helper info')
t.end()
})
})
Expand Down

0 comments on commit 996248c

Please sign in to comment.