1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
const t = require('tap')
const { join, resolve, basename, extname, dirname } = require('path')
const fs = require('@npmcli/fs')
const localeCompare = require('@isaacs/string-locale-compare')('en')
const docs = require('@npmcli/docs')
const { load: loadMockNpm } = require('../fixtures/mock-npm.js')
const mockGlobals = require('../fixtures/mock-globals.js')
const { definitions } = require('../../lib/utils/config/index.js')
const cmdList = require('../../lib/utils/cmd-list.js')
const pkg = require('../../package.json')
t.test('command list', async t => {
for (const [key, value] of Object.entries(cmdList)) {
t.matchSnapshot(value, key)
}
})
t.test('shorthands', async t => {
t.matchSnapshot(docs.shorthands(docs.TAGS.SHORTHANDS, {}), 'docs')
})
t.test('config', async t => {
const keys = Object.keys(definitions)
const flat = Object.entries(definitions).filter(([_, d]) => d.flatten).map(([k]) => k)
const notFlat = keys.filter(k => !flat.includes(k))
t.matchSnapshot(keys, 'all keys')
t.matchSnapshot(flat, 'keys that are flattened')
t.matchSnapshot(notFlat, 'keys that are not flattened')
t.matchSnapshot(docs.config(docs.TAGS.CONFIG, {}), 'all definitions')
})
t.test('basic usage', async t => {
mockGlobals(t, { process: { platform: 'posix' } })
t.cleanSnapshot = str => str
.split(dirname(dirname(__dirname))).join('{BASEDIR}')
.split(pkg.version).join('{VERSION}')
// snapshot basic usage without commands since all the command snapshots
// are generated in the following test
const { npm } = await loadMockNpm(t, {
mocks: {
'../../lib/utils/cmd-list.js': { commands: [] },
},
})
npm.config.set('userconfig', '/some/config/file/.npmrc')
t.matchSnapshot(await npm.usage)
})
t.test('usage', async t => {
const readdir = async (dir, ext) => {
const files = await fs.readdir(dir)
return files.filter(f => extname(f) === ext).map(f => basename(f, ext))
}
const fsCommands = await readdir(resolve(__dirname, '../../lib/commands'), '.js')
const docsCommands = await readdir(join(docs.paths.content, 'commands'), docs.DOC_EXT)
const bareCommands = ['npm', 'npx']
// XXX: These extra commands exist as js files but not as docs pages
const allDocs = docsCommands.concat(['get', 'set', 'll']).map(n => n.replace('npm-', ''))
// ensure that the list of js files in commands, docs files, and the command list
// are all in sync. eg, this will error if a command is removed but not its docs file
t.strictSame(
fsCommands.sort(localeCompare),
cmdList.allCommands,
'command list and fs are the same'
)
t.strictSame(
allDocs.filter(f => !bareCommands.includes(f)).sort(localeCompare),
cmdList.allCommands,
'command list and docs files are the same'
)
// use the list of files from the docs since those include the special cases
// for the bare npm and npx usage
for (const cmd of allDocs) {
t.test(cmd, async t => {
let output = null
if (!bareCommands.includes(cmd)) {
const { npm } = await loadMockNpm(t)
const impl = await npm.cmd(cmd)
output = impl.usage
}
const usage = docs.usage(docs.TAGS.USAGE, { path: cmd })
const params = docs.params(docs.TAGS.CONFIG, { path: cmd })
.split('\n')
.filter(l => l.startsWith('#### '))
.join('\n') || 'NO PARAMS'
t.matchSnapshot([output, usage, params].filter(Boolean).join('\n\n'))
})
}
})
|