summaryrefslogtreecommitdiff
path: root/deps/npm/test/lib/utils
diff options
context:
space:
mode:
authornpm CLI robot <npm-cli+bot@github.com>2023-03-31 06:38:48 -0700
committerGitHub <noreply@github.com>2023-03-31 13:38:48 +0000
commit0517e19310281bb8ab95afa8a29d02cd0de07354 (patch)
tree3f037182eae8eab9ae361dc92e1bce51d2d0bae9 /deps/npm/test/lib/utils
parentb74b9ddb7b0161e7090a9ec2fd2b1358b17b0e23 (diff)
downloadnode-new-0517e19310281bb8ab95afa8a29d02cd0de07354.tar.gz
deps: upgrade npm to 9.6.3
PR-URL: https://github.com/nodejs/node/pull/47325 Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Luke Karrys <luke@lukekarrys.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Diffstat (limited to 'deps/npm/test/lib/utils')
-rw-r--r--deps/npm/test/lib/utils/display.js2
-rw-r--r--deps/npm/test/lib/utils/error-message.js31
-rw-r--r--deps/npm/test/lib/utils/exit-handler.js33
-rw-r--r--deps/npm/test/lib/utils/explain-dep.js15
-rw-r--r--deps/npm/test/lib/utils/explain-eresolve.js28
-rw-r--r--deps/npm/test/lib/utils/log-file.js14
-rw-r--r--deps/npm/test/lib/utils/update-notifier.js324
7 files changed, 223 insertions, 224 deletions
diff --git a/deps/npm/test/lib/utils/display.js b/deps/npm/test/lib/utils/display.js
index cfe0181e23..7a99dcb679 100644
--- a/deps/npm/test/lib/utils/display.js
+++ b/deps/npm/test/lib/utils/display.js
@@ -58,7 +58,7 @@ t.test('can log', async (t) => {
display.log('warn', 'ERESOLVE', 'hello', { some: 'object' })
t.match(logs.warn, [['ERESOLVE', 'hello']])
- t.match(explains, [[{ some: 'object' }, false, 2]])
+ t.match(explains, [[{ some: 'object' }, null, 2]])
})
t.test('handles log throwing', async (t) => {
diff --git a/deps/npm/test/lib/utils/error-message.js b/deps/npm/test/lib/utils/error-message.js
index 9d07693989..37b3bc6afe 100644
--- a/deps/npm/test/lib/utils/error-message.js
+++ b/deps/npm/test/lib/utils/error-message.js
@@ -384,6 +384,27 @@ t.test('bad platform', async t => {
t.matchSnapshot(errorMessage(er))
t.end()
})
+ t.test('omits keys with no required value', t => {
+ const er = Object.assign(new Error('a bad plat'), {
+ pkgid: 'lodash@1.0.0',
+ current: {
+ os: 'posix',
+ cpu: 'x64',
+ libc: 'musl',
+ },
+ required: {
+ os: ['!yours', 'mine'],
+ libc: [], // empty arrays should also lead to a key being removed
+ cpu: undefined, // XXX npm-install-checks sets unused keys to undefined
+ },
+ code: 'EBADPLATFORM',
+ })
+ const msg = errorMessage(er)
+ t.matchSnapshot(msg)
+ t.notMatch(msg, /Valid cpu/, 'omits cpu from message')
+ t.notMatch(msg, /Valid libc/, 'omits libc from message')
+ t.end()
+ })
})
t.test('explain ERESOLVE errors', async t => {
@@ -393,11 +414,14 @@ t.test('explain ERESOLVE errors', async t => {
errorMocks: {
'{LIB}/utils/explain-eresolve.js': {
report: (...args) => {
- EXPLAIN_CALLED.push(args)
+ EXPLAIN_CALLED.push(...args)
return { explanation: 'explanation', file: 'report' }
},
},
},
+ config: {
+ color: 'always',
+ },
})
const er = Object.assign(new Error('could not resolve'), {
@@ -405,5 +429,8 @@ t.test('explain ERESOLVE errors', async t => {
})
t.matchSnapshot(errorMessage(er))
- t.match(EXPLAIN_CALLED, [[er, false]])
+ t.equal(EXPLAIN_CALLED.length, 3)
+ t.match(EXPLAIN_CALLED, [er, Function, Function])
+ t.not(EXPLAIN_CALLED[1].level, 0, 'color chalk level is not 0')
+ t.equal(EXPLAIN_CALLED[2].level, 0, 'colorless chalk level is 0')
})
diff --git a/deps/npm/test/lib/utils/exit-handler.js b/deps/npm/test/lib/utils/exit-handler.js
index 76d5fec4c0..969bd05a98 100644
--- a/deps/npm/test/lib/utils/exit-handler.js
+++ b/deps/npm/test/lib/utils/exit-handler.js
@@ -27,6 +27,9 @@ t.formatSnapshot = (obj) => {
t.cleanSnapshot = (path) => cleanDate(cleanCwd(path))
// Config loading is dependent on env so strip those from snapshots
.replace(/.*timing config:load:.*\n/gm, '')
+ // logfile cleaning is not awaited so it races with the process.exit
+ // in this test and can cause snapshot failures so we always remove them
+ .replace(/.*silly logfile.*cleaning.*\n/gm, '')
.replace(/(Completed in )\d+(ms)/g, '$1{TIME}$2')
.replace(/(removing )\d+( files)/g, '$1${NUM}2')
@@ -106,13 +109,11 @@ const mockExitHandler = async (t, { init, load, testdir, config, mocks, files }
errors,
npm,
// Make it async to make testing ergonomics a little easier so we dont need
- // to t.plan() every test to make sure we get process.exit called. Also
- // introduce a small artificial delay so the logs are consistently finished
- // by the time the exit handler forces process.exit
- exitHandler: (...args) => new Promise(res => setTimeout(() => {
+ // to t.plan() every test to make sure we get process.exit called.
+ exitHandler: (...args) => new Promise(res => {
process.once('exit', res)
exitHandler(...args)
- }, 50)),
+ }),
}
}
@@ -134,30 +135,32 @@ t.test('handles unknown error with logs and debug file', async (t) => {
await exitHandler(err('Unknown error', 'ECODE'))
- const debugContent = await debugFile()
+ const fileLogs = await debugFile()
+ const fileLines = fileLogs.split('\n')
+
+ const lineNumber = /^(\d+)\s/
+ const lastLog = fileLines[fileLines.length - 1].match(lineNumber)[1]
t.equal(process.exitCode, 1)
+
logs.forEach((logItem, i) => {
const logLines = format(i, ...logItem).trim().split(os.EOL)
logLines.forEach((line) => {
- t.match(debugContent.trim(), line, 'log appears in debug file')
+ t.match(fileLogs.trim(), line, 'log appears in debug file')
})
})
- const lastLog = debugContent
- .split('\n')
- .reduce((__, l) => parseInt(l.match(/^(\d+)\s/)[1]))
- t.equal(logs.length, lastLog + 1)
+ t.equal(logs.length, parseInt(lastLog) + 1)
t.match(logs.error, [
['code', 'ECODE'],
['ERR SUMMARY', 'Unknown error'],
['ERR DETAIL', 'Unknown error'],
])
- t.match(debugContent, /\d+ error code ECODE/)
- t.match(debugContent, /\d+ error ERR SUMMARY Unknown error/)
- t.match(debugContent, /\d+ error ERR DETAIL Unknown error/)
+ t.match(fileLogs, /\d+ error code ECODE/)
+ t.match(fileLogs, /\d+ error ERR SUMMARY Unknown error/)
+ t.match(fileLogs, /\d+ error ERR DETAIL Unknown error/)
t.matchSnapshot(logs, 'logs')
- t.matchSnapshot(debugContent, 'debug file contents')
+ t.matchSnapshot(fileLines.map(l => l.replace(lineNumber, 'XX ')), 'debug file contents')
})
t.test('exit handler never called - loglevel silent', async (t) => {
diff --git a/deps/npm/test/lib/utils/explain-dep.js b/deps/npm/test/lib/utils/explain-dep.js
index 514f28d125..e5389fd26d 100644
--- a/deps/npm/test/lib/utils/explain-dep.js
+++ b/deps/npm/test/lib/utils/explain-dep.js
@@ -1,9 +1,12 @@
const { resolve } = require('path')
const t = require('tap')
+const Chalk = require('chalk')
const { explainNode, printNode } = require('../../../lib/utils/explain-dep.js')
const { cleanCwd } = require('../../fixtures/clean-snapshot')
const testdir = t.testdirName
+const color = new Chalk.Instance({ level: Chalk.level })
+const noColor = new Chalk.Instance({ level: 0 })
t.cleanSnapshot = (str) => cleanCwd(str)
@@ -250,10 +253,10 @@ cases.workspaces = {
for (const [name, expl] of Object.entries(cases)) {
t.test(name, t => {
- t.matchSnapshot(printNode(expl, true), 'print color')
- t.matchSnapshot(printNode(expl, false), 'print nocolor')
- t.matchSnapshot(explainNode(expl, Infinity, true), 'explain color deep')
- t.matchSnapshot(explainNode(expl, 2, false), 'explain nocolor shallow')
+ t.matchSnapshot(printNode(expl, color), 'print color')
+ t.matchSnapshot(printNode(expl, noColor), 'print nocolor')
+ t.matchSnapshot(explainNode(expl, Infinity, color), 'explain color deep')
+ t.matchSnapshot(explainNode(expl, 2, noColor), 'explain nocolor shallow')
t.end()
})
}
@@ -261,6 +264,6 @@ for (const [name, expl] of Object.entries(cases)) {
// make sure that we show the last one if it's the only one that would
// hit the ...
cases.manyDeps.dependents.pop()
-t.matchSnapshot(explainNode(cases.manyDeps, 2, false), 'ellipses test one')
+t.matchSnapshot(explainNode(cases.manyDeps, 2, noColor), 'ellipses test one')
cases.manyDeps.dependents.pop()
-t.matchSnapshot(explainNode(cases.manyDeps, 2, false), 'ellipses test two')
+t.matchSnapshot(explainNode(cases.manyDeps, 2, noColor), 'ellipses test two')
diff --git a/deps/npm/test/lib/utils/explain-eresolve.js b/deps/npm/test/lib/utils/explain-eresolve.js
index 2c1fed7789..0f60556ef2 100644
--- a/deps/npm/test/lib/utils/explain-eresolve.js
+++ b/deps/npm/test/lib/utils/explain-eresolve.js
@@ -1,9 +1,11 @@
const t = require('tap')
-const { resolve } = require('path')
+const Chalk = require('chalk')
const { explain, report } = require('../../../lib/utils/explain-eresolve.js')
const cases = require('../../fixtures/eresolve-explanations.js')
-const { cleanDate } = require('../../fixtures/clean-snapshot.js')
+
+const color = new Chalk.Instance({ level: Chalk.level })
+const noColor = new Chalk.Instance({ level: 0 })
for (const [name, expl] of Object.entries(cases)) {
// no sense storing the whole contents of each object in the snapshot
@@ -11,22 +13,16 @@ for (const [name, expl] of Object.entries(cases)) {
expl.toJSON = () => ({ name, json: true })
t.test(name, t => {
- const dir = t.testdir()
- const fileReport = resolve(dir, 'eresolve-report.txt')
- const opts = { file: fileReport, date: new Date().toISOString() }
-
- t.cleanSnapshot = str => cleanDate(str.split(fileReport).join('${REPORT}'))
-
- const color = report(expl, true, opts)
- t.matchSnapshot(color.explanation, 'report with color')
- t.matchSnapshot(color.file, 'report from color')
+ const colorReport = report(expl, color, noColor)
+ t.matchSnapshot(colorReport.explanation, 'report with color')
+ t.matchSnapshot(colorReport.file, 'report from color')
- const noColor = report(expl, false, opts)
- t.matchSnapshot(noColor.explanation, 'report with no color')
- t.equal(noColor.file, color.file, 'same report written for object')
+ const noColorReport = report(expl, noColor, noColor)
+ t.matchSnapshot(noColorReport.explanation, 'report with no color')
+ t.equal(noColorReport.file, colorReport.file, 'same report written for object')
- t.matchSnapshot(explain(expl, true, 2), 'explain with color, depth of 2')
- t.matchSnapshot(explain(expl, false, 6), 'explain with no color, depth of 6')
+ t.matchSnapshot(explain(expl, color, 2), 'explain with color, depth of 2')
+ t.matchSnapshot(explain(expl, noColor, 6), 'explain with no color, depth of 6')
t.end()
})
diff --git a/deps/npm/test/lib/utils/log-file.js b/deps/npm/test/lib/utils/log-file.js
index e134fe8790..fde17dee96 100644
--- a/deps/npm/test/lib/utils/log-file.js
+++ b/deps/npm/test/lib/utils/log-file.js
@@ -255,6 +255,20 @@ t.test('glob error', async t => {
t.match(last(logs).content, /error cleaning log files .* bad glob/)
})
+t.test('do not log cleaning errors when logging is disabled', async t => {
+ const { readLogs } = await loadLogFile(t, {
+ logsMax: 0,
+ mocks: {
+ glob: () => {
+ throw new Error('should not be logged')
+ },
+ },
+ })
+
+ const logs = await readLogs()
+ t.equal(logs.length, 0)
+})
+
t.test('cleans old style logs too', async t => {
const logsMax = 5
const oldLogs = 10
diff --git a/deps/npm/test/lib/utils/update-notifier.js b/deps/npm/test/lib/utils/update-notifier.js
index e7830e6d9d..9c12433a2d 100644
--- a/deps/npm/test/lib/utils/update-notifier.js
+++ b/deps/npm/test/lib/utils/update-notifier.js
@@ -1,10 +1,8 @@
const t = require('tap')
+const { basename } = require('path')
const tmock = require('../../fixtures/tmock')
+const mockNpm = require('../../fixtures/mock-npm')
-let ciMock = {}
-const flatOptions = { global: false, cache: t.testdir() + '/_cacache' }
-
-const MANIFEST_REQUEST = []
const CURRENT_VERSION = '123.420.69'
const CURRENT_MAJOR = '122.420.69'
const CURRENT_MINOR = '123.419.69'
@@ -15,238 +13,196 @@ const NEXT_PATCH = '123.421.69'
const CURRENT_BETA = '124.0.0-beta.99999'
const HAVE_BETA = '124.0.0-beta.0'
-let PACOTE_ERROR = null
-const pacote = {
- manifest: async (spec, opts) => {
- if (!spec.match(/^npm@/)) {
- process.exit(1)
- }
- MANIFEST_REQUEST.push(spec)
- if (PACOTE_ERROR) {
- throw PACOTE_ERROR
- }
-
- return {
- version:
- spec === 'npm@latest'
- ? CURRENT_VERSION
- : /-/.test(spec)
- ? CURRENT_BETA
- : NEXT_VERSION,
- }
- },
-}
-
-const defaultNpm = {
- flatOptions,
- version: CURRENT_VERSION,
- config: { get: k => k !== 'global' },
- command: 'view',
- argv: ['npm'],
-}
-
-const { basename } = require('path')
-
-let STAT_ERROR = null
-let STAT_MTIME = null
-let WRITE_ERROR = null
-const fs = {
- ...require('fs'),
- stat: (path, cb) => {
- if (basename(path) !== '_update-notifier-last-checked') {
- process.exit(1)
- }
- process.nextTick(() => cb(STAT_ERROR, { mtime: new Date(STAT_MTIME) }))
- },
- writeFile: (path, content, cb) => {
- if (content !== '') {
- process.exit(1)
- }
- if (basename(path) !== '_update-notifier-last-checked') {
- process.exit(1)
- }
- process.nextTick(() => cb(WRITE_ERROR))
- },
+const runUpdateNotifier = async (t, {
+ STAT_ERROR,
+ WRITE_ERROR,
+ PACOTE_ERROR,
+ STAT_MTIME = 0,
+ mocks: _mocks = {},
+ command = 'view',
+ version = CURRENT_VERSION,
+ argv = [],
+ ...config
+} = {}) => {
+ const mockFs = {
+ ...require('fs/promises'),
+ stat: async (path) => {
+ if (basename(path) !== '_update-notifier-last-checked') {
+ t.fail('no stat allowed for non upate notifier files')
+ }
+ if (STAT_ERROR) {
+ throw STAT_ERROR
+ }
+ return { mtime: new Date(STAT_MTIME) }
+ },
+ writeFile: async (path, content) => {
+ if (content !== '') {
+ t.fail('no write file content allowed')
+ }
+ if (basename(path) !== '_update-notifier-last-checked') {
+ t.fail('no writefile allowed for non upate notifier files')
+ }
+ if (WRITE_ERROR) {
+ throw WRITE_ERROR
+ }
+ },
+ }
+
+ const MANIFEST_REQUEST = []
+ const mockPacote = {
+ manifest: async (spec) => {
+ if (!spec.match(/^npm@/)) {
+ t.fail('no pacote manifest allowed for non npm packages')
+ }
+ MANIFEST_REQUEST.push(spec)
+ if (PACOTE_ERROR) {
+ throw PACOTE_ERROR
+ }
+ const manifestV = spec === 'npm@latest' ? CURRENT_VERSION
+ : /-/.test(spec) ? CURRENT_BETA : NEXT_VERSION
+ return { version: manifestV }
+ },
+ }
+
+ const mocks = {
+ pacote: mockPacote,
+ 'fs/promises': mockFs,
+ '{ROOT}/package.json': { version },
+ 'ci-info': { isCI: false, name: null },
+ ..._mocks,
+ }
+
+ const mock = await mockNpm(t, {
+ command,
+ mocks,
+ config,
+ argv,
+ })
+ const updateNotifier = tmock(t, '{LIB}/utils/update-notifier.js', mocks)
+
+ const result = await updateNotifier(mock.npm)
+
+ return {
+ result,
+ MANIFEST_REQUEST,
+ }
}
-t.afterEach(() => {
- MANIFEST_REQUEST.length = 0
- STAT_ERROR = null
- PACOTE_ERROR = null
- STAT_MTIME = null
- WRITE_ERROR = null
+t.test('does not notify by default', async t => {
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t)
+ t.not(result)
+ t.equal(MANIFEST_REQUEST.length, 1)
})
-const runUpdateNotifier = async ({ color = true, ...npmOptions } = {}) => {
- const _npm = { ...defaultNpm, ...npmOptions, logColor: color }
- return tmock(t, '{LIB}/utils/update-notifier.js', {
- 'ci-info': ciMock,
- pacote,
- fs,
- })(_npm)
-}
-
t.test('situations in which we do not notify', t => {
t.test('nothing to do if notifier disabled', async t => {
- t.equal(
- await runUpdateNotifier({
- config: { get: k => k !== 'update-notifier' },
- }),
- null
- )
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, {
+ 'update-notifier': false,
+ })
+ t.equal(result, null)
t.strictSame(MANIFEST_REQUEST, [], 'no requests for manifests')
})
t.test('do not suggest update if already updating', async t => {
- t.equal(
- await runUpdateNotifier({
- flatOptions: { ...flatOptions, global: true },
- command: 'install',
- argv: ['npm'],
- }),
- null
- )
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, {
+ command: 'install',
+ argv: ['npm'],
+ global: true,
+ })
+ t.equal(result, null)
t.strictSame(MANIFEST_REQUEST, [], 'no requests for manifests')
})
t.test('do not suggest update if already updating with spec', async t => {
- t.equal(
- await runUpdateNotifier({
- flatOptions: { ...flatOptions, global: true },
- command: 'install',
- argv: ['npm@latest'],
- }),
- null
- )
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, {
+ command: 'install',
+ argv: ['npm@latest'],
+ global: true,
+ })
+ t.equal(result, null)
t.strictSame(MANIFEST_REQUEST, [], 'no requests for manifests')
})
t.test('do not update if same as latest', async t => {
- t.equal(await runUpdateNotifier(), null)
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t)
+ t.equal(result, null)
t.strictSame(MANIFEST_REQUEST, ['npm@latest'], 'requested latest version')
})
t.test('check if stat errors (here for coverage)', async t => {
- STAT_ERROR = new Error('blorg')
- t.equal(await runUpdateNotifier(), null)
+ const STAT_ERROR = new Error('blorg')
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, { STAT_ERROR })
+ t.equal(result, null)
t.strictSame(MANIFEST_REQUEST, ['npm@latest'], 'requested latest version')
})
t.test('ok if write errors (here for coverage)', async t => {
- WRITE_ERROR = new Error('grolb')
- t.equal(await runUpdateNotifier(), null)
+ const WRITE_ERROR = new Error('grolb')
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, { WRITE_ERROR })
+ t.equal(result, null)
t.strictSame(MANIFEST_REQUEST, ['npm@latest'], 'requested latest version')
})
t.test('ignore pacote failures (here for coverage)', async t => {
- PACOTE_ERROR = new Error('pah-KO-tchay')
- t.equal(await runUpdateNotifier(), null)
+ const PACOTE_ERROR = new Error('pah-KO-tchay')
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, { PACOTE_ERROR })
+ t.equal(result, null)
t.strictSame(MANIFEST_REQUEST, ['npm@latest'], 'requested latest version')
})
t.test('do not update if newer than latest, but same as next', async t => {
- t.equal(await runUpdateNotifier({ version: NEXT_VERSION }), null)
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, { version: NEXT_VERSION })
+ t.equal(result, null)
const reqs = ['npm@latest', `npm@^${NEXT_VERSION}`]
t.strictSame(MANIFEST_REQUEST, reqs, 'requested latest and next versions')
})
t.test('do not update if on the latest beta', async t => {
- t.equal(await runUpdateNotifier({ version: CURRENT_BETA }), null)
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, { version: CURRENT_BETA })
+ t.equal(result, null)
const reqs = [`npm@^${CURRENT_BETA}`]
t.strictSame(MANIFEST_REQUEST, reqs, 'requested latest and next versions')
})
t.test('do not update in CI', async t => {
- t.teardown(() => {
- ciMock = {}
- })
- ciMock = { isCI: true, name: 'something' }
- t.equal(await runUpdateNotifier(), null)
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, { mocks: {
+ 'ci-info': { isCI: true, name: 'something' },
+ } })
+ t.equal(result, null)
t.strictSame(MANIFEST_REQUEST, [], 'no requests for manifests')
})
t.test('only check weekly for GA releases', async t => {
// One week (plus five minutes to account for test environment fuzziness)
- STAT_MTIME = Date.now() - 1000 * 60 * 60 * 24 * 7 + 1000 * 60 * 5
- t.equal(await runUpdateNotifier(), null)
+ const STAT_MTIME = Date.now() - 1000 * 60 * 60 * 24 * 7 + 1000 * 60 * 5
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, { STAT_MTIME })
+ t.equal(result, null)
t.strictSame(MANIFEST_REQUEST, [], 'no requests for manifests')
})
t.test('only check daily for betas', async t => {
// One day (plus five minutes to account for test environment fuzziness)
- STAT_MTIME = Date.now() - 1000 * 60 * 60 * 24 + 1000 * 60 * 5
- t.equal(await runUpdateNotifier({ version: HAVE_BETA }), null)
- t.strictSame(MANIFEST_REQUEST, [], 'no requests for manifests')
+ const STAT_MTIME = Date.now() - 1000 * 60 * 60 * 24 + 1000 * 60 * 5
+ const res = await runUpdateNotifier(t, { STAT_MTIME, version: HAVE_BETA })
+ t.equal(res.result, null)
+ t.strictSame(res.MANIFEST_REQUEST, [], 'no requests for manifests')
})
t.end()
})
-t.test('notification situations', t => {
- t.test('new beta available', async t => {
- const version = HAVE_BETA
- t.matchSnapshot(await runUpdateNotifier({ version }), 'color')
- t.matchSnapshot(
- await runUpdateNotifier({ version, color: false }),
- 'no color'
- )
- t.strictSame(MANIFEST_REQUEST, [`npm@^${version}`, `npm@^${version}`])
- })
-
- t.test('patch to next version', async t => {
- const version = NEXT_PATCH
- t.matchSnapshot(await runUpdateNotifier({ version }), 'color')
- t.matchSnapshot(
- await runUpdateNotifier({ version, color: false }),
- 'no color'
- )
- t.strictSame(MANIFEST_REQUEST, [
- 'npm@latest',
- `npm@^${version}`,
- 'npm@latest',
- `npm@^${version}`,
- ])
- })
-
- t.test('minor to next version', async t => {
- const version = NEXT_MINOR
- t.matchSnapshot(await runUpdateNotifier({ version }), 'color')
- t.matchSnapshot(
- await runUpdateNotifier({ version, color: false }),
- 'no color'
- )
- t.strictSame(MANIFEST_REQUEST, [
- 'npm@latest',
- `npm@^${version}`,
- 'npm@latest',
- `npm@^${version}`,
- ])
- })
-
- t.test('patch to current', async t => {
- const version = CURRENT_PATCH
- t.matchSnapshot(await runUpdateNotifier({ version }), 'color')
- t.matchSnapshot(
- await runUpdateNotifier({ version, color: false }),
- 'no color'
- )
- t.strictSame(MANIFEST_REQUEST, ['npm@latest', 'npm@latest'])
- })
-
- t.test('minor to current', async t => {
- const version = CURRENT_MINOR
- t.matchSnapshot(await runUpdateNotifier({ version }), 'color')
- t.matchSnapshot(
- await runUpdateNotifier({ version, color: false }),
- 'no color'
- )
- t.strictSame(MANIFEST_REQUEST, ['npm@latest', 'npm@latest'])
- })
-
- t.test('major to current', async t => {
- const version = CURRENT_MAJOR
- t.matchSnapshot(await runUpdateNotifier({ version }), 'color')
- t.matchSnapshot(
- await runUpdateNotifier({ version, color: false }),
- 'no color'
- )
- t.strictSame(MANIFEST_REQUEST, ['npm@latest', 'npm@latest'])
- })
-
- t.end()
+t.test('notification situations', async t => {
+ const cases = {
+ [HAVE_BETA]: [`^{V}`],
+ [NEXT_PATCH]: [`latest`, `^{V}`],
+ [NEXT_MINOR]: [`latest`, `^{V}`],
+ [CURRENT_PATCH]: ['latest'],
+ [CURRENT_MINOR]: ['latest'],
+ [CURRENT_MAJOR]: ['latest'],
+ }
+
+ for (const [version, reqs] of Object.entries(cases)) {
+ for (const color of [false, 'always']) {
+ await t.test(`${version} - color=${color}`, async t => {
+ const { result, MANIFEST_REQUEST } = await runUpdateNotifier(t, { version, color })
+ t.matchSnapshot(result)
+ t.strictSame(MANIFEST_REQUEST, reqs.map(r => `npm@${r.replace('{V}', version)}`))
+ })
+ }
+ }
})