Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'test/lib/npm.js')
-rw-r--r--test/lib/npm.js528
1 files changed, 261 insertions, 267 deletions
diff --git a/test/lib/npm.js b/test/lib/npm.js
index 1ccd26e37..2a0c5a89d 100644
--- a/test/lib/npm.js
+++ b/test/lib/npm.js
@@ -1,7 +1,8 @@
const t = require('tap')
+const { resolve, dirname } = require('path')
-const npmlog = require('npmlog')
-const { real: mockNpm } = require('../fixtures/mock-npm.js')
+const { load: loadMockNpm } = require('../fixtures/mock-npm.js')
+const mockGlobals = require('../fixtures/mock-globals')
// delete this so that we don't have configs from the fact that it
// is being run by 'npm test'
@@ -15,7 +16,7 @@ for (const env of Object.keys(process.env).filter(e => /^npm_/.test(e))) {
// if this test is just run directly, which is also acceptable.
if (event === 'test') {
t.ok(
- ['test', 'run-script'].some(i => i === event),
+ ['test', 'run-script'].some(i => i === process.env[env]),
'should match "npm test" or "npm run test"'
)
} else {
@@ -25,41 +26,14 @@ for (const env of Object.keys(process.env).filter(e => /^npm_/.test(e))) {
delete process.env[env]
}
-const { resolve, dirname } = require('path')
-
-const actualPlatform = process.platform
-const beWindows = () => {
- Object.defineProperty(process, 'platform', {
- value: 'win32',
- configurable: true,
- })
-}
-const bePosix = () => {
- Object.defineProperty(process, 'platform', {
- value: 'posix',
- configurable: true,
- })
-}
-const argv = [...process.argv]
-
-t.afterEach(() => {
+t.afterEach(async (t) => {
for (const env of Object.keys(process.env).filter(e => /^npm_/.test(e))) {
delete process.env[env]
}
- process.env.npm_config_cache = CACHE
- process.argv = argv
- Object.defineProperty(process, 'platform', {
- value: actualPlatform,
- configurable: true,
- })
})
-const CACHE = t.testdir()
-process.env.npm_config_cache = CACHE
-
t.test('not yet loaded', async t => {
- const { Npm, logs } = mockNpm(t)
- const npm = new Npm()
+ const { npm, logs } = await loadMockNpm(t, { load: false })
t.match(npm, {
started: Number,
command: null,
@@ -79,8 +53,7 @@ t.test('not yet loaded', async t => {
t.test('npm.load', async t => {
t.test('load error', async t => {
- const { Npm } = mockNpm(t)
- const npm = new Npm()
+ const { npm } = await loadMockNpm(t, { load: false })
const loadError = new Error('load error')
npm.config.load = async () => {
throw loadError
@@ -103,32 +76,28 @@ t.test('npm.load', async t => {
})
t.test('basic loading', async t => {
- const { Npm, logs } = mockNpm(t)
- const npm = new Npm()
- const dir = t.testdir({
- node_modules: {},
+ const { npm, logs, prefix: dir, cache } = await loadMockNpm(t, {
+ testdir: { node_modules: {} },
})
- await npm.load()
+
t.equal(npm.loaded, true)
t.equal(npm.config.loaded, true)
t.equal(npm.config.get('force'), false)
t.ok(npm.usage, 'has usage')
- npm.config.set('prefix', dir)
t.match(npm, {
flatOptions: {},
})
- t.match(logs, [
- ['timing', 'npm:load', /Completed in [0-9.]+ms/],
+ t.match(logs.timing.filter(([p]) => p === 'npm:load'), [
+ ['npm:load', /Completed in [0-9.]+ms/],
])
- bePosix()
- t.equal(resolve(npm.cache), resolve(CACHE), 'cache is cache')
+ mockGlobals(t, { process: { platform: 'posix' } })
+ t.equal(resolve(npm.cache), resolve(cache), 'cache is cache')
const newCache = t.testdir()
npm.cache = newCache
t.equal(npm.config.get('cache'), newCache, 'cache setter sets config')
t.equal(npm.cache, newCache, 'cache getter gets new config')
- t.equal(npm.log, npmlog, 'npmlog getter')
t.equal(npm.lockfileVersion, 2, 'lockfileVersion getter')
t.equal(npm.prefix, npm.localPrefix, 'prefix is local prefix')
t.not(npm.prefix, npm.globalPrefix, 'prefix is not global prefix')
@@ -160,10 +129,9 @@ t.test('npm.load', async t => {
t.equal(npm.bin, npm.globalBin, 'bin is global bin after prefix setter')
t.not(npm.bin, npm.localBin, 'bin is not local bin after prefix setter')
- beWindows()
+ mockGlobals(t, { process: { platform: 'win32' } })
t.equal(npm.bin, npm.globalBin, 'bin is global bin in windows mode')
t.equal(npm.dir, npm.globalDir, 'dir is global dir in windows mode')
- bePosix()
const tmp = npm.tmp
t.match(tmp, String, 'npm.tmp is a string')
@@ -171,13 +139,12 @@ t.test('npm.load', async t => {
})
t.test('forceful loading', async t => {
- process.argv = [...process.argv, '--force', '--color', 'always']
- const { Npm, logs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- t.match(logs.filter(l => l[0] !== 'timing'), [
+ mockGlobals(t, {
+ 'process.argv': [...process.argv, '--force', '--color', 'always'],
+ })
+ const { logs } = await loadMockNpm(t)
+ t.match(logs.warn, [
[
- 'warn',
'using --force',
'Recommended protections disabled.',
],
@@ -185,54 +152,42 @@ t.test('npm.load', async t => {
})
t.test('node is a symlink', async t => {
- const node = actualPlatform === 'win32' ? 'node.exe' : 'node'
- const dir = t.testdir({
- '.npmrc': 'foo = bar',
- bin: t.fixture('symlink', dirname(process.execPath)),
+ const node = process.platform === 'win32' ? 'node.exe' : 'node'
+ mockGlobals(t, {
+ 'process.argv': [
+ node,
+ process.argv[1],
+ '--usage',
+ '--scope=foo',
+ 'token',
+ 'revoke',
+ 'blergggg',
+ ],
})
-
- const PATH = process.env.PATH || process.env.Path
- process.env.PATH = resolve(dir, 'bin')
- process.argv = [
- node,
- process.argv[1],
- '--prefix', dir,
- '--userconfig', `${dir}/.npmrc`,
- '--usage',
- '--scope=foo',
- 'token',
- 'revoke',
- 'blergggg',
- ]
-
- t.teardown(() => {
- process.env.PATH = PATH
+ const { npm, logs, outputs, prefix } = await loadMockNpm(t, {
+ testdir: {
+ bin: t.fixture('symlink', dirname(process.execPath)),
+ },
+ globals: ({ prefix }) => ({
+ 'process.env.PATH': resolve(prefix, 'bin'),
+ }),
})
- const { Npm, logs, outputs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
t.equal(npm.config.get('scope'), '@foo', 'added the @ sign to scope')
- t.match(logs.filter(l => l[0] !== 'timing' || !/^config:/.test(l[1])), [
- [
- 'timing',
- 'npm:load:whichnode',
- /Completed in [0-9.]+ms/,
- ],
- [
- 'verbose',
- 'node symlink',
- resolve(dir, 'bin', node),
- ],
- [
- 'timing',
- 'npm:load',
- /Completed in [0-9.]+ms/,
- ],
+ t.match([
+ ...logs.timing.filter(([p]) => p === 'npm:load:whichnode'),
+ ...logs.verbose,
+ ...logs.timing.filter(([p]) => p === 'npm:load'),
+ ], [
+ ['npm:load:whichnode', /Completed in [0-9.]+ms/],
+ ['node symlink', resolve(prefix, 'bin', node)],
+ ['logfile', /.*-debug-0.log/],
+ ['npm:load', /Completed in [0-9.]+ms/],
])
- t.equal(process.execPath, resolve(dir, 'bin', node))
+ t.equal(process.execPath, resolve(prefix, 'bin', node))
outputs.length = 0
+ logs.length = 0
await npm.exec('ll', [])
t.equal(npm.command, 'll', 'command set to first npm command')
@@ -271,33 +226,34 @@ t.test('npm.load', async t => {
})
t.test('--no-workspaces with --workspace', async t => {
- const dir = t.testdir({
- packages: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- scripts: { test: 'echo test a' },
- }),
+ mockGlobals(t, {
+ 'process.argv': [
+ process.execPath,
+ process.argv[1],
+ '--color', 'false',
+ '--workspaces', 'false',
+ '--workspace', 'a',
+ ],
+ })
+ const { npm } = await loadMockNpm(t, {
+ load: false,
+ testdir: {
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ scripts: { test: 'echo test a' },
+ }),
+ },
},
+ 'package.json': JSON.stringify({
+ name: 'root',
+ version: '1.0.0',
+ workspaces: ['./packages/*'],
+ }),
},
- 'package.json': JSON.stringify({
- name: 'root',
- version: '1.0.0',
- workspaces: ['./packages/*'],
- }),
})
- process.argv = [
- process.execPath,
- process.argv[1],
- '--userconfig', resolve(dir, '.npmrc'),
- '--color', 'false',
- '--workspaces', 'false',
- '--workspace', 'a',
- ]
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- npm.localPrefix = dir
await t.rejects(
npm.exec('run', []),
/Can not use --no-workspaces and --workspace at the same time/
@@ -305,47 +261,40 @@ t.test('npm.load', async t => {
})
t.test('workspace-aware configs and commands', async t => {
- const dir = t.testdir({
- packages: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- scripts: { test: 'echo test a' },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- scripts: { test: 'echo test b' },
- }),
+ mockGlobals(t, {
+ 'process.argv': [
+ process.execPath,
+ process.argv[1],
+ '--color', 'false',
+ '--workspaces', 'true',
+ ],
+ })
+ const { npm, outputs } = await loadMockNpm(t, {
+ testdir: {
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ scripts: { test: 'echo test a' },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ scripts: { test: 'echo test b' },
+ }),
+ },
},
+ 'package.json': JSON.stringify({
+ name: 'root',
+ version: '1.0.0',
+ workspaces: ['./packages/*'],
+ }),
},
- 'package.json': JSON.stringify({
- name: 'root',
- version: '1.0.0',
- workspaces: ['./packages/*'],
- }),
- '.npmrc': '',
})
- process.argv = [
- process.execPath,
- process.argv[1],
- '--userconfig',
- resolve(dir, '.npmrc'),
- '--color',
- 'false',
- '--workspaces',
- 'true',
- ]
-
- const { Npm, outputs } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.localPrefix = dir
-
// verify that calling the command with a short name still sets
// the npm.command property to the full canonical name of the cmd.
npm.command = null
@@ -368,44 +317,42 @@ t.test('npm.load', async t => {
})
t.test('workspaces in global mode', async t => {
- const dir = t.testdir({
- packages: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- scripts: { test: 'echo test a' },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- scripts: { test: 'echo test b' },
- }),
+ mockGlobals(t, {
+ 'process.argv': [
+ process.execPath,
+ process.argv[1],
+ '--color',
+ 'false',
+ '--workspaces',
+ '--global',
+ 'true',
+ ],
+ })
+ const { npm } = await loadMockNpm(t, {
+ testdir: {
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ scripts: { test: 'echo test a' },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ scripts: { test: 'echo test b' },
+ }),
+ },
},
+ 'package.json': JSON.stringify({
+ name: 'root',
+ version: '1.0.0',
+ workspaces: ['./packages/*'],
+ }),
},
- 'package.json': JSON.stringify({
- name: 'root',
- version: '1.0.0',
- workspaces: ['./packages/*'],
- }),
})
- process.argv = [
- process.execPath,
- process.argv[1],
- '--userconfig',
- resolve(dir, '.npmrc'),
- '--color',
- 'false',
- '--workspaces',
- '--global',
- 'true',
- ]
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
- npm.localPrefix = dir
// verify that calling the command with a short name still sets
// the npm.command property to the full canonical name of the cmd.
npm.command = null
@@ -418,109 +365,156 @@ t.test('npm.load', async t => {
t.test('set process.title', async t => {
t.test('basic title setting', async t => {
- process.argv = [
- process.execPath,
- process.argv[1],
- '--usage',
- '--scope=foo',
- 'ls',
- ]
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
+ mockGlobals(t, {
+ 'process.argv': [
+ process.execPath,
+ process.argv[1],
+ '--usage',
+ '--scope=foo',
+ 'ls',
+ ],
+ })
+ const { npm } = await loadMockNpm(t)
t.equal(npm.title, 'npm ls')
t.equal(process.title, 'npm ls')
})
t.test('do not expose token being revoked', async t => {
- process.argv = [
- process.execPath,
- process.argv[1],
- '--usage',
- '--scope=foo',
- 'token',
- 'revoke',
- 'deadbeefcafebad',
- ]
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
+ mockGlobals(t, {
+ 'process.argv': [
+ process.execPath,
+ process.argv[1],
+ '--usage',
+ '--scope=foo',
+ 'token',
+ 'revoke',
+ 'deadbeefcafebad',
+ ],
+ })
+ const { npm } = await loadMockNpm(t)
t.equal(npm.title, 'npm token revoke ***')
t.equal(process.title, 'npm token revoke ***')
})
t.test('do show *** unless a token is actually being revoked', async t => {
- process.argv = [
- process.execPath,
- process.argv[1],
- '--usage',
- '--scope=foo',
- 'token',
- 'revoke',
- ]
- const { Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
+ mockGlobals(t, {
+ 'process.argv': [
+ process.execPath,
+ process.argv[1],
+ '--usage',
+ '--scope=foo',
+ 'token',
+ 'revoke',
+ ],
+ })
+ const { npm } = await loadMockNpm(t)
t.equal(npm.title, 'npm token revoke')
t.equal(process.title, 'npm token revoke')
})
})
-t.test('timings', t => {
- const { Npm, logs } = mockNpm(t)
- const npm = new Npm()
- process.emit('time', 'foo')
- process.emit('time', 'bar')
- t.match(npm.timers.get('foo'), Number, 'foo timer is a number')
- t.match(npm.timers.get('bar'), Number, 'foo timer is a number')
- process.emit('timeEnd', 'foo')
- process.emit('timeEnd', 'bar')
- process.emit('timeEnd', 'baz')
- t.match(logs, [
- ['timing', 'foo', /Completed in [0-9]+ms/],
- ['timing', 'bar', /Completed in [0-9]+ms/],
- [
- 'silly',
+t.test('debug-log', async t => {
+ const { npm, debugFile } = await loadMockNpm(t, { load: false })
+
+ const log1 = ['silly', 'test', 'before load']
+ const log2 = ['silly', 'test', 'after load']
+
+ process.emit('log', ...log1)
+ await npm.load()
+ process.emit('log', ...log2)
+
+ const debug = await debugFile()
+ t.equal(npm.logFiles.length, 1, 'one debug file')
+ t.match(debug, log1.join(' '), 'before load appears')
+ t.match(debug, log2.join(' '), 'after load log appears')
+})
+
+t.test('timings', async t => {
+ t.test('gets/sets timers', async t => {
+ const { npm, logs } = await loadMockNpm(t, { load: false })
+ process.emit('time', 'foo')
+ process.emit('time', 'bar')
+ t.match(npm.unfinishedTimers.get('foo'), Number, 'foo timer is a number')
+ t.match(npm.unfinishedTimers.get('bar'), Number, 'foo timer is a number')
+ process.emit('timeEnd', 'foo')
+ process.emit('timeEnd', 'bar')
+ process.emit('timeEnd', 'baz')
+ // npm timer is started by default
+ process.emit('timeEnd', 'npm')
+ t.match(logs.timing, [
+ ['foo', /Completed in [0-9]+ms/],
+ ['bar', /Completed in [0-9]+ms/],
+ ['npm', /Completed in [0-9]+ms/],
+ ])
+ t.match(logs.silly, [[
'timing',
"Tried to end timer that doesn't exist:",
'baz',
- ],
- ])
- t.notOk(npm.timers.has('foo'), 'foo timer is gone')
- t.notOk(npm.timers.has('bar'), 'bar timer is gone')
- t.match(npm.timings, { foo: Number, bar: Number })
- t.end()
+ ]])
+ t.notOk(npm.unfinishedTimers.has('foo'), 'foo timer is gone')
+ t.notOk(npm.unfinishedTimers.has('bar'), 'bar timer is gone')
+ t.match(npm.finishedTimers, { foo: Number, bar: Number, npm: Number })
+ t.end()
+ })
+
+ t.test('writes timings file', async t => {
+ const { npm, timingFile } = await loadMockNpm(t, {
+ config: { timing: true },
+ })
+ process.emit('time', 'foo')
+ process.emit('timeEnd', 'foo')
+ process.emit('time', 'bar')
+ npm.unload()
+ const timings = await timingFile()
+ t.match(timings, {
+ command: [],
+ logfile: String,
+ logfiles: [String],
+ version: String,
+ unfinished: {
+ bar: [Number, Number],
+ npm: [Number, Number],
+ },
+ foo: Number,
+ 'npm:load': Number,
+ })
+ })
+
+ t.test('does not write timings file with timers:false', async t => {
+ const { npm, timingFile } = await loadMockNpm(t, {
+ config: { false: true },
+ })
+ npm.unload()
+ await t.rejects(() => timingFile())
+ })
})
-t.test('output clears progress and console.logs the message', t => {
- const mock = mockNpm(t)
- const { Npm, logs } = mock
- const npm = new Npm()
- npm.output = mock.npmOutput
- const { log } = console
- const { log: { clearProgress, showProgress } } = npm
+t.test('output clears progress and console.logs the message', async t => {
+ t.plan(2)
let showingProgress = true
- npm.log.clearProgress = () => showingProgress = false
- npm.log.showProgress = () => showingProgress = true
- console.log = (...args) => {
- t.equal(showingProgress, false, 'should not be showing progress right now')
- logs.push(args)
- }
- t.teardown(() => {
- console.log = log
- npm.log.showProgress = showProgress
- npm.log.clearProgress = clearProgress
+ const logs = []
+ mockGlobals(t, {
+ 'console.log': (...args) => {
+ t.equal(showingProgress, false, 'should not be showing progress right now')
+ logs.push(args)
+ },
})
-
- npm.output('hello')
- t.strictSame(logs, [['hello']])
+ const { npm } = await loadMockNpm(t, {
+ load: false,
+ mocks: {
+ npmlog: {
+ clearProgress: () => showingProgress = false,
+ showProgress: () => showingProgress = true,
+ },
+ },
+ })
+ npm.originalOutput('hello')
+ t.match(logs, [['hello']])
t.end()
})
t.test('unknown command', async t => {
- const mock = mockNpm(t)
- const { Npm } = mock
- const npm = new Npm()
+ const { npm } = await loadMockNpm(t, { load: false })
await t.rejects(
npm.cmd('thisisnotacommand'),
{ code: 'EUNKNOWNCOMMAND' }