Skip to content

Commit b062c4a

Browse files
committed
fix(tests): move more tests to use real npm
This moves a handful of the smaller tests to using the new npm mock that uses the real actual npm object. It also extends the testing surface area of a few tests back down into the actual `process.spawn` that results, instead of anything internal to the code. Some dead code in `lib/test.js` was found during this, as well as an instance of a module throwing a string instead of an error object.
1 parent 23ce3af commit b062c4a

File tree

18 files changed

+272
-204
lines changed

18 files changed

+272
-204
lines changed

lib/set.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class Set extends BaseCommand {
2222

2323
exec (args, cb) {
2424
if (!args.length)
25-
return cb(this.usage)
25+
return cb(this.usageError())
2626
this.npm.commands.config(['set'].concat(args), cb)
2727
}
2828
}

lib/test.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,5 @@ class Test extends LifecycleCmd {
1919
'script-shell',
2020
]
2121
}
22-
23-
exec (args, cb) {
24-
super.exec(args, er => {
25-
if (er && er.code === 'ELIFECYCLE') {
26-
/* eslint-disable standard/no-callback-literal */
27-
cb('Test failed. See above for more details.')
28-
} else
29-
cb(er)
30-
})
31-
}
3222
}
3323
module.exports = Test

node_modules/.gitignore

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
"@npmcli/arborist",
127127
"@npmcli/ci-detect",
128128
"@npmcli/config",
129+
"@npmcli/package-json",
129130
"@npmcli/run-script",
130131
"abbrev",
131132
"ansicolors",
@@ -198,6 +199,7 @@
198199
"eslint-plugin-promise": "^5.1.0",
199200
"eslint-plugin-standard": "^5.0.0",
200201
"licensee": "^8.2.0",
202+
"spawk": "^1.7.1",
201203
"tap": "^15.0.9"
202204
},
203205
"scripts": {

test/fixtures/mock-npm.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ for (const level of ['silly', 'verbose', 'timing', 'notice', 'warn', 'error'])
1111
const { title, execPath } = process
1212

1313
const RealMockNpm = (t, otherMocks = {}) => {
14+
t.afterEach(() => {
15+
outputs.length = 0
16+
logs.length = 0
17+
})
1418
t.teardown(() => {
1519
for (const level of ['silly', 'verbose', 'timing', 'notice', 'warn', 'error'])
1620
npmlog[level] = realLog[level]
@@ -23,6 +27,9 @@ const RealMockNpm = (t, otherMocks = {}) => {
2327
})
2428
const logs = []
2529
const outputs = []
30+
const joinedOutput = () => {
31+
return outputs.map(o => o.join(' ')).join('\n')
32+
}
2633
const npm = t.mock('../../lib/npm.js', otherMocks)
2734
const command = async (command, args = []) => {
2835
return new Promise((resolve, reject) => {
@@ -39,7 +46,7 @@ const RealMockNpm = (t, otherMocks = {}) => {
3946
}
4047
}
4148
npm.output = (...msg) => outputs.push(msg)
42-
return { npm, logs, outputs, command }
49+
return { npm, logs, outputs, command, joinedOutput }
4350
}
4451

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

test/lib/find-dupes.js

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
const t = require('tap')
22

3-
const FindDupes = require('../../lib/find-dupes.js')
3+
const { real: mockNpm } = require('../fixtures/mock-npm')
44

5-
t.test('should run dedupe in dryRun mode', (t) => {
6-
t.plan(3)
7-
const findDupesTest = new FindDupes({
8-
config: {
9-
set: (k, v) => {
10-
t.match(k, 'dry-run')
11-
t.match(v, true)
12-
},
5+
t.test('should run dedupe in dryRun mode', async (t) => {
6+
t.plan(5)
7+
const { npm, command } = mockNpm(t, {
8+
'@npmcli/arborist': function (args) {
9+
t.ok(args, 'gets options object')
10+
t.ok(args.path, 'gets path option')
11+
t.ok(args.dryRun, 'is called in dryRun mode')
12+
this.dedupe = () => {
13+
t.ok(true, 'dedupe is called')
14+
}
1315
},
14-
commands: {
15-
dedupe: (args, cb) => {
16-
t.match(args, [])
17-
cb()
18-
},
16+
'../../lib/utils/reify-finish.js': (npm, arb) => {
17+
t.ok(arb, 'gets arborist tree')
1918
},
2019
})
21-
findDupesTest.exec({}, () => {
22-
t.end()
23-
})
20+
await npm.load()
21+
// explicitly set to false so we can be 100% sure it's always true when it
22+
// hits arborist
23+
npm.config.set('dry-run', false)
24+
npm.config.set('prefix', 'foo')
25+
await command('find-dupes')
2426
})

test/lib/get.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
const t = require('tap')
2+
const { real: mockNpm } = require('../fixtures/mock-npm')
23

3-
t.test('should retrieve values from npm.commands.config', (t) => {
4-
const Get = t.mock('../../lib/get.js')
5-
const get = new Get({
6-
commands: {
7-
config: ([action, arg]) => {
8-
t.equal(action, 'get', 'should use config get action')
9-
t.equal(arg, 'foo', 'should use expected key')
10-
t.end()
11-
},
12-
},
13-
})
14-
15-
get.exec(['foo'])
4+
t.test('should retrieve values from config', async t => {
5+
const { joinedOutput, command, npm } = mockNpm(t)
6+
const name = 'editor'
7+
const value = 'vigor'
8+
await npm.load()
9+
npm.config.set(name, value)
10+
await command('get', [name])
11+
t.equal(
12+
joinedOutput(),
13+
value,
14+
'outputs config item'
15+
)
1616
})

test/lib/load-all.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
const t = require('tap')
22
const glob = require('glob')
33
const { resolve } = require('path')
4+
const { real: mockNpm } = require('../fixtures/mock-npm')
45

56
const full = process.env.npm_lifecycle_event === 'check-coverage'
67

78
if (!full)
89
t.pass('nothing to do here, not checking for full coverage')
910
else {
10-
// some files do config.get() on load, so have to load npm first
11-
const npm = require('../../lib/npm.js')
12-
t.test('load npm first', t => npm.load(t.end))
11+
const { npm } = mockNpm(t)
12+
13+
t.teardown(() => {
14+
const exitHandler = require('../../lib/utils/exit-handler.js')
15+
exitHandler()
16+
})
17+
18+
t.test('load npm first', async t => {
19+
await npm.load()
20+
})
1321

1422
t.test('load all the files', t => {
1523
// just load all the files so we measure coverage for the missing tests
@@ -21,11 +29,4 @@ else {
2129
t.pass('loaded all files')
2230
t.end()
2331
})
24-
25-
t.test('call the exit handler so we dont freak out', t => {
26-
const exitHandler = require('../../lib/utils/exit-handler.js')
27-
exitHandler.setNpm(npm)
28-
exitHandler()
29-
t.end()
30-
})
3132
}

test/lib/prefix.js

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
const t = require('tap')
2+
const { real: mockNpm } = require('../fixtures/mock-npm')
23

3-
t.test('prefix', (t) => {
4-
t.plan(3)
5-
const dir = '/prefix/dir'
6-
7-
const Prefix = require('../../lib/prefix.js')
8-
const prefix = new Prefix({
9-
prefix: dir,
10-
output: (output) => {
11-
t.equal(output, dir, 'prints the correct directory')
12-
},
13-
})
14-
15-
prefix.exec([], (err) => {
16-
t.error(err, 'npm prefix')
17-
t.ok('should have printed directory')
18-
})
4+
t.test('prefix', async (t) => {
5+
const { joinedOutput, command, npm } = mockNpm(t)
6+
await npm.load()
7+
await command('prefix')
8+
t.equal(
9+
joinedOutput(),
10+
npm.prefix,
11+
'outputs npm.prefix'
12+
)
1913
})

0 commit comments

Comments
 (0)