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
path: root/test
diff options
context:
space:
mode:
authornlf <quitlahok@gmail.com>2020-12-10 20:45:46 +0300
committerisaacs <i@izs.me>2020-12-11 22:33:16 +0300
commit7a4f0c96c2ab9f264f7bda2caf7e72c881571270 (patch)
tree78f820f3372bc87ae10ae43cc27debb4488b1183 /test
parentd825e901eceea4cf8d860e35238dc30008eb4da4 (diff)
tests for npm doctornlf/doctor-tests
PR-URL: https://github.com/npm/cli/pull/2323 Credit: @nlf Close: #2323 Reviewed-by: @isaacs
Diffstat (limited to 'test')
-rw-r--r--test/lib/doctor.js943
1 files changed, 943 insertions, 0 deletions
diff --git a/test/lib/doctor.js b/test/lib/doctor.js
new file mode 100644
index 000000000..c2c3fdb97
--- /dev/null
+++ b/test/lib/doctor.js
@@ -0,0 +1,943 @@
+const { test } = require('tap')
+const requireInject = require('require-inject')
+
+const { join } = require('path')
+const fs = require('fs')
+const ansiTrim = require('../../lib/utils/ansi-trim.js')
+const isWindows = require('../../lib/utils/is-windows.js')
+
+// getuid and getgid do not exist in windows, so we shim them
+// to return 0, as that is the value that lstat will assign the
+// gid and uid properties for fs.Stats objects
+if (isWindows) {
+ process.getuid = () => 0
+ process.getgid = () => 0
+}
+
+const output = []
+
+let pingError
+const ping = async () => {
+ if (pingError)
+ throw pingError
+}
+
+const nodeVersions = [
+ { version: 'v14.0.0', lts: false },
+ { version: 'v13.0.0', lts: false },
+ // it's necessary to allow tests in node 10.x to not mark 12.x as lts
+ { version: 'v12.0.0', lts: false },
+ { version: 'v10.13.0', lts: 'Dubnium' },
+]
+
+const fetch = async () => {
+ return {
+ json: async () => {
+ return nodeVersions
+ },
+ }
+}
+
+const logs = {
+ info: [],
+}
+
+const clearLogs = (obj = logs) => {
+ output.length = 0
+ for (const key in obj) {
+ if (Array.isArray(obj[key]))
+ obj[key].length = 0
+ else
+ delete obj[key]
+ }
+}
+
+const npm = {
+ flatOptions: {
+ registry: 'https://registry.npmjs.org/',
+ },
+ log: {
+ info: (msg) => {
+ logs.info.push(msg)
+ },
+ newItem: (name) => {
+ logs[name] = {}
+
+ return {
+ info: (_, msg) => {
+ if (!logs[name].info)
+ logs[name].info = []
+ logs[name].info.push(msg)
+ },
+ warn: (_, msg) => {
+ if (!logs[name].warn)
+ logs[name].warn = []
+ logs[name].warn.push(msg)
+ },
+ error: (_, msg) => {
+ if (!logs[name].error)
+ logs[name].error = []
+ logs[name].error.push(msg)
+ },
+ silly: (_, msg) => {
+ if (!logs[name].silly)
+ logs[name].silly = []
+ logs[name].silly.push(msg)
+ },
+ completeWork: () => {},
+ finish: () => {
+ logs[name].finished = true
+ },
+ }
+ },
+ level: 'error',
+ levels: {
+ info: 1,
+ error: 0,
+ },
+ },
+ version: '7.1.0',
+}
+
+let latestNpm = npm.version
+const pacote = {
+ manifest: async () => {
+ return { version: latestNpm }
+ },
+}
+
+let whichError = null
+const which = async () => {
+ if (whichError)
+ throw whichError
+ return '/path/to/git'
+}
+
+let verifyResponse = { verifiedCount: 1, verifiedContent: 1 }
+const cacache = {
+ verify: async () => {
+ return verifyResponse
+ },
+}
+
+const doctor = requireInject('../../lib/doctor.js', {
+ '../../lib/utils/is-windows.js': false,
+ '../../lib/utils/ping.js': ping,
+ '../../lib/utils/output.js': (data) => {
+ output.push(data)
+ },
+ '../../lib/npm.js': npm,
+ cacache,
+ pacote,
+ 'make-fetch-happen': fetch,
+ which,
+})
+
+test('npm doctor checks ok', t => {
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ if (err) {
+ t.fail(output)
+ return t.end()
+ }
+
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping\s*ok/, 'ping output is ok')
+ t.match(output, /npm -v\s*ok/, 'npm -v output is ok')
+ t.match(output, /node -v\s*ok/, 'node -v output is ok')
+ t.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok')
+ t.match(output, /which git\s*ok/, 'which git output is ok')
+ t.match(output, /cached files\s*ok/, 'cached files are ok')
+ t.match(output, /local node_modules\s*ok/, 'local node_modules are ok')
+ t.match(output, /global node_modules\s*ok/, 'global node_modules are ok')
+ t.match(output, /local bin folder\s*ok/, 'local bin is ok')
+ t.match(output, /global bin folder\s*ok/, 'global bin is ok')
+ t.match(output, /cache contents\s*ok/, 'cache contents is ok')
+ t.end()
+ })
+})
+
+test('npm doctor supports silent', t => {
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+ npm.log.level = 'info'
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ npm.log.level = 'error'
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ if (err) {
+ t.fail(err)
+ return t.end()
+ }
+
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.strictSame(output, [], 'did not print output')
+ t.end()
+ })
+})
+
+test('npm doctor supports color', t => {
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+ npm.color = true
+ pingError = { message: 'generic error' }
+ const _consoleError = console.error
+ console.error = () => {}
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ delete npm.color
+ pingError = null
+ console.error = _consoleError
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ t.match(err, /Some problems found/, 'detected the ping error')
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping.*not ok/, 'ping output is ok')
+ t.match(output, /npm -v.*ok/, 'npm -v output is ok')
+ t.match(output, /node -v.*ok/, 'node -v output is ok')
+ t.match(output, /npm config get registry.*ok.*using default/, 'npm config get registry output is ok')
+ t.match(output, /which git.*ok/, 'which git output is ok')
+ t.match(output, /cached files.*ok/, 'cached files are ok')
+ t.match(output, /local node_modules.*ok/, 'local node_modules are ok')
+ t.match(output, /global node_modules.*ok/, 'global node_modules are ok')
+ t.match(output, /local bin folder.*ok/, 'local bin is ok')
+ t.match(output, /global bin folder.*ok/, 'global bin is ok')
+ t.match(output, /cache contents.*ok/, 'cache contents is ok')
+ t.notEqual(output[0], ansiTrim(output[0]), 'output should contain color codes')
+ t.end()
+ })
+})
+
+test('npm doctor skips some tests in windows', t => {
+ const winDoctor = requireInject('../../lib/doctor.js', {
+ '../../lib/utils/is-windows.js': true,
+ '../../lib/utils/ping.js': ping,
+ '../../lib/utils/output.js': (data) => {
+ output.push(data)
+ },
+ '../../lib/npm.js': npm,
+ cacache,
+ pacote,
+ 'make-fetch-happen': fetch,
+ which,
+ })
+
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ clearLogs()
+ })
+
+ winDoctor([], (err) => {
+ if (err) {
+ t.fail(output)
+ return t.end()
+ }
+
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: undefined,
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping\s*ok/, 'ping output is ok')
+ t.match(output, /npm -v\s*ok/, 'npm -v output is ok')
+ t.match(output, /node -v\s*ok/, 'node -v output is ok')
+ t.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok')
+ t.match(output, /which git\s*ok/, 'which git output is ok')
+ t.match(output, /cache contents\s*ok/, 'cache contents is ok')
+ t.end()
+ })
+})
+
+test('npm doctor ping error E{3}', t => {
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+ pingError = { code: 'E111', message: 'this error is 111' }
+ const consoleError = console.error
+ // we just print an empty line here, so swallow it and ignore
+ console.error = () => {}
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ pingError = null
+ console.error = consoleError
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ t.match(err, /Some problems found/, 'detected the ping error')
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping\s*not ok\s*111 this error is 111/, 'ping output contains trimmed error')
+ t.match(output, /npm -v\s*ok/, 'npm -v output is ok')
+ t.match(output, /node -v\s*ok/, 'node -v output is ok')
+ t.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok')
+ t.match(output, /which git\s*ok/, 'which git output is ok')
+ t.match(output, /cached files\s*ok/, 'cached files are ok')
+ t.match(output, /local node_modules\s*ok/, 'local node_modules are ok')
+ t.match(output, /global node_modules\s*ok/, 'global node_modules are ok')
+ t.match(output, /local bin folder\s*ok/, 'local bin is ok')
+ t.match(output, /global bin folder\s*ok/, 'global bin is ok')
+ t.match(output, /cache contents\s*ok/, 'cache contents is ok')
+ t.end()
+ })
+})
+
+test('npm doctor generic ping error', t => {
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+ pingError = { message: 'generic error' }
+ const consoleError = console.error
+ // we just print an empty line here, so swallow it and ignore
+ console.error = () => {}
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ pingError = null
+ console.error = consoleError
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ t.match(err, /Some problems found/, 'detected the ping error')
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping\s*not ok\s*generic error/, 'ping output contains trimmed error')
+ t.match(output, /npm -v\s*ok/, 'npm -v output is ok')
+ t.match(output, /node -v\s*ok/, 'node -v output is ok')
+ t.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok')
+ t.match(output, /which git\s*ok/, 'which git output is ok')
+ t.match(output, /cached files\s*ok/, 'cached files are ok')
+ t.match(output, /local node_modules\s*ok/, 'local node_modules are ok')
+ t.match(output, /global node_modules\s*ok/, 'global node_modules are ok')
+ t.match(output, /local bin folder\s*ok/, 'local bin is ok')
+ t.match(output, /global bin folder\s*ok/, 'global bin is ok')
+ t.match(output, /cache contents\s*ok/, 'cache contents is ok')
+ t.end()
+ })
+})
+
+test('npm doctor outdated npm version', t => {
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+ latestNpm = '7.1.1'
+ const consoleError = console.error
+ // we just print an empty line here, so swallow it and ignore
+ console.error = () => {}
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ latestNpm = npm.version
+ console.error = consoleError
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ t.match(err, /Some problems found/, 'detected the out of date npm')
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping\s*ok/, 'ping output is ok')
+ t.match(output, /npm -v\s*not ok/, 'npm -v output is not ok')
+ t.match(output, /node -v\s*ok/, 'node -v output is ok')
+ t.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok')
+ t.match(output, /which git\s*ok/, 'which git output is ok')
+ t.match(output, /cached files\s*ok/, 'cached files are ok')
+ t.match(output, /local node_modules\s*ok/, 'local node_modules are ok')
+ t.match(output, /global node_modules\s*ok/, 'global node_modules are ok')
+ t.match(output, /local bin folder\s*ok/, 'local bin is ok')
+ t.match(output, /global bin folder\s*ok/, 'global bin is ok')
+ t.match(output, /cache contents\s*ok/, 'cache contents is ok')
+ t.end()
+ })
+})
+
+test('npm doctor outdated nodejs version', t => {
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+ nodeVersions.push({ version: process.version.replace(/\d+$/, '999'), lts: false })
+ const consoleError = console.error
+ // we just print an empty line here, so swallow it and ignore
+ console.error = () => {}
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ nodeVersions.pop()
+ console.error = consoleError
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ t.match(err, /Some problems found/, 'detected the out of date nodejs')
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping\s*ok/, 'ping output is ok')
+ t.match(output, /npm -v\s*ok/, 'npm -v output is ok')
+ t.match(output, /node -v\s*not ok/, 'node -v output is not ok')
+ t.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok')
+ t.match(output, /which git\s*ok/, 'which git output is ok')
+ t.match(output, /cached files\s*ok/, 'cached files are ok')
+ t.match(output, /local node_modules\s*ok/, 'local node_modules are ok')
+ t.match(output, /global node_modules\s*ok/, 'global node_modules are ok')
+ t.match(output, /local bin folder\s*ok/, 'local bin is ok')
+ t.match(output, /global bin folder\s*ok/, 'global bin is ok')
+ t.match(output, /cache contents\s*ok/, 'cache contents is ok')
+ t.end()
+ })
+})
+
+test('npm doctor file permission checks', t => {
+ const dir = t.testdir({
+ cache: {
+ one: 'one',
+ link: t.fixture('symlink', './one'),
+ unreadable: 'unreadable',
+ baddir: {},
+ },
+ local: {
+ two: 'two',
+ notmine: 'notmine',
+ },
+ global: {
+ three: 'three',
+ broken: 'broken',
+ },
+ localBin: {
+ four: 'four',
+ five: 'five',
+ },
+ globalBin: {
+ six: 'six',
+ seven: 'seven',
+ },
+ })
+
+ const _fsLstat = fs.lstat
+ fs.lstat = (p, cb) => {
+ let err = null
+ let stat = null
+
+ try {
+ stat = fs.lstatSync(p)
+ } catch (err) {
+ return cb(err)
+ }
+
+ switch (p) {
+ case join(dir, 'local', 'notmine'):
+ stat.uid += 1
+ stat.gid += 1
+ break
+ case join(dir, 'global', 'broken'):
+ err = new Error('broken')
+ break
+ }
+
+ return cb(err, stat)
+ }
+
+ const _fsReaddir = fs.readdir
+ fs.readdir = (p, cb) => {
+ let err = null
+ let result = null
+
+ try {
+ result = fs.readdirSync(p)
+ } catch (err) {
+ return cb(err)
+ }
+
+ if (p === join(dir, 'cache', 'baddir'))
+ err = new Error('broken')
+
+ return cb(err, result)
+ }
+
+ const _fsAccess = fs.access
+ fs.access = (p, mask, cb) => {
+ const err = new Error('failed')
+ switch (p) {
+ case join(dir, 'cache', 'unreadable'):
+ case join(dir, 'localBin', 'four'):
+ case join(dir, 'globalBin', 'six'):
+ return cb(err)
+ default:
+ return cb(null)
+ }
+ }
+
+ const doctor = requireInject('../../lib/doctor.js', {
+ '../../lib/utils/is-windows.js': false,
+ '../../lib/utils/ping.js': ping,
+ '../../lib/utils/output.js': (data) => {
+ output.push(data)
+ },
+ '../../lib/npm.js': npm,
+ cacache,
+ pacote,
+ 'make-fetch-happen': fetch,
+ which,
+ fs,
+ })
+ // it's necessary to allow tests in node 10.x to not mark 12.x as lted
+
+ npm.cache = npm.flatOptions.cache = join(dir, 'cache')
+ npm.localDir = join(dir, 'local')
+ npm.globalDir = join(dir, 'global')
+ npm.localBin = join(dir, 'localBin')
+ npm.globalBin = join(dir, 'globalBin')
+ const _consoleError = console.error
+ console.error = () => {}
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ console.error = _consoleError
+ fs.lstat = _fsLstat
+ fs.readdir = _fsReaddir
+ fs.access = _fsAccess
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ t.match(err, /Some problems found/, 'identified problems')
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [join(dir, 'cache')]: { finished: true },
+ [join(dir, 'local')]: { finished: true },
+ [join(dir, 'global')]: { finished: true },
+ [join(dir, 'localBin')]: { finished: true },
+ [join(dir, 'globalBin')]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping\s*ok/, 'ping output is ok')
+ t.match(output, /npm -v\s*ok/, 'npm -v output is ok')
+ t.match(output, /node -v\s*ok/, 'node -v output is ok')
+ t.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok')
+ t.match(output, /which git\s*ok/, 'which git output is ok')
+ t.match(output, /cached files\s*not ok/, 'cached files are not ok')
+ t.match(output, /local node_modules\s*not ok/, 'local node_modules are not ok')
+ t.match(output, /global node_modules\s*not ok/, 'global node_modules are not ok')
+ t.match(output, /local bin folder\s*not ok/, 'local bin is not ok')
+ t.match(output, /global bin folder\s*not ok/, 'global bin is not ok')
+ t.match(output, /cache contents\s*ok/, 'cache contents is ok')
+ t.end()
+ })
+})
+
+test('npm doctor missing git', t => {
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+ whichError = new Error('boom')
+ const consoleError = console.error
+ // we just print an empty line here, so swallow it and ignore
+ console.error = () => {}
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ whichError = null
+ console.error = consoleError
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ t.match(err, /Some problems found/, 'detected the missing git')
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping\s*ok/, 'ping output is ok')
+ t.match(output, /npm -v\s*ok/, 'npm -v output is ok')
+ t.match(output, /node -v\s*ok/, 'node -v output is ok')
+ t.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok')
+ t.match(output, /which git\s*not ok/, 'which git output is not ok')
+ t.match(output, /cached files\s*ok/, 'cached files are ok')
+ t.match(output, /local node_modules\s*ok/, 'local node_modules are ok')
+ t.match(output, /global node_modules\s*ok/, 'global node_modules are ok')
+ t.match(output, /local bin folder\s*ok/, 'local bin is ok')
+ t.match(output, /global bin folder\s*ok/, 'global bin is ok')
+ t.match(output, /cache contents\s*ok/, 'cache contents is ok')
+ t.end()
+ })
+})
+
+test('npm doctor cache verification showed bad content', t => {
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+ const _verifyResponse = verifyResponse
+ verifyResponse = {
+ ...verifyResponse,
+ badContentCount: 1,
+ }
+ const consoleError = console.error
+ // we just print an empty line here, so swallow it and ignore
+ console.error = () => {}
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ verifyResponse = _verifyResponse
+ console.error = consoleError
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ // cache verification problems get fixed and so do not throw an error
+ if (err) {
+ t.fail(output)
+ return t.end()
+ }
+
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping\s*ok/, 'ping output is ok')
+ t.match(output, /npm -v\s*ok/, 'npm -v output is ok')
+ t.match(output, /node -v\s*ok/, 'node -v output is ok')
+ t.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok')
+ t.match(output, /which git\s*ok/, 'which git output is ok')
+ t.match(output, /cached files\s*ok/, 'cached files are ok')
+ t.match(output, /local node_modules\s*ok/, 'local node_modules are ok')
+ t.match(output, /global node_modules\s*ok/, 'global node_modules are ok')
+ t.match(output, /local bin folder\s*ok/, 'local bin is ok')
+ t.match(output, /global bin folder\s*ok/, 'global bin is ok')
+ t.match(output, /cache contents\s*ok/, 'cache contents is not ok')
+ t.end()
+ })
+})
+
+test('npm doctor cache verification showed reclaimed content', t => {
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+ const _verifyResponse = verifyResponse
+ verifyResponse = {
+ ...verifyResponse,
+ reclaimedCount: 1,
+ reclaimedSize: 100,
+ }
+ const consoleError = console.error
+ // we just print an empty line here, so swallow it and ignore
+ console.error = () => {}
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ verifyResponse = _verifyResponse
+ console.error = consoleError
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ // cache verification problems get fixed and so do not throw an error
+ if (err) {
+ t.fail(output)
+ return t.end()
+ }
+
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping\s*ok/, 'ping output is ok')
+ t.match(output, /npm -v\s*ok/, 'npm -v output is ok')
+ t.match(output, /node -v\s*ok/, 'node -v output is ok')
+ t.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok')
+ t.match(output, /which git\s*ok/, 'which git output is ok')
+ t.match(output, /cached files\s*ok/, 'cached files are ok')
+ t.match(output, /local node_modules\s*ok/, 'local node_modules are ok')
+ t.match(output, /global node_modules\s*ok/, 'global node_modules are ok')
+ t.match(output, /local bin folder\s*ok/, 'local bin is ok')
+ t.match(output, /global bin folder\s*ok/, 'global bin is ok')
+ t.match(output, /cache contents\s*ok/, 'cache contents is not ok')
+ t.end()
+ })
+})
+
+test('npm doctor cache verification showed missing content', t => {
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+ const _verifyResponse = verifyResponse
+ verifyResponse = {
+ ...verifyResponse,
+ missingContent: 1,
+ }
+ const consoleError = console.error
+ // we just print an empty line here, so swallow it and ignore
+ console.error = () => {}
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ verifyResponse = _verifyResponse
+ console.error = consoleError
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ // cache verification problems get fixed and so do not throw an error
+ if (err) {
+ t.fail(output)
+ return t.end()
+ }
+
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping\s*ok/, 'ping output is ok')
+ t.match(output, /npm -v\s*ok/, 'npm -v output is ok')
+ t.match(output, /node -v\s*ok/, 'node -v output is ok')
+ t.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok')
+ t.match(output, /which git\s*ok/, 'which git output is ok')
+ t.match(output, /cached files\s*ok/, 'cached files are ok')
+ t.match(output, /local node_modules\s*ok/, 'local node_modules are ok')
+ t.match(output, /global node_modules\s*ok/, 'global node_modules are ok')
+ t.match(output, /local bin folder\s*ok/, 'local bin is ok')
+ t.match(output, /global bin folder\s*ok/, 'global bin is ok')
+ t.match(output, /cache contents\s*ok/, 'cache contents is not ok')
+ t.end()
+ })
+})
+
+test('npm doctor not using default registry', t => {
+ const dir = t.testdir()
+ npm.cache = npm.flatOptions.cache = dir
+ npm.localDir = dir
+ npm.globalDir = dir
+ npm.localBin = dir
+ npm.globalBin = dir
+ const _currentRegistry = npm.flatOptions.registry
+ npm.flatOptions.registry = 'https://google.com'
+ const consoleError = console.error
+ // we just print an empty line here, so swallow it and ignore
+ console.error = () => {}
+
+ t.teardown(() => {
+ delete npm.cache
+ delete npm.flatOptions.cache
+ delete npm.localDir
+ delete npm.globalDir
+ delete npm.localBin
+ delete npm.globalBin
+ npm.flatOptions.registry = _currentRegistry
+ console.error = consoleError
+ clearLogs()
+ })
+
+ doctor([], (err) => {
+ // cache verification problems get fixed and so do not throw an error
+ t.match(err, /Some problems found/, 'detected the non-default registry')
+ t.match(logs, {
+ checkPing: { finished: true },
+ getLatestNpmVersion: { finished: true },
+ getLatestNodejsVersion: { finished: true },
+ getGitPath: { finished: true },
+ [dir]: { finished: true },
+ verifyCachedFiles: { finished: true },
+ }, 'trackers all finished')
+ t.match(output, /npm ping\s*ok/, 'ping output is ok')
+ t.match(output, /npm -v\s*ok/, 'npm -v output is ok')
+ t.match(output, /node -v\s*ok/, 'node -v output is ok')
+ t.match(output, /npm config get registry\s*not ok/, 'npm config get registry output is not ok')
+ t.match(output, /which git\s*ok/, 'which git output is ok')
+ t.match(output, /cached files\s*ok/, 'cached files are ok')
+ t.match(output, /local node_modules\s*ok/, 'local node_modules are ok')
+ t.match(output, /global node_modules\s*ok/, 'global node_modules are ok')
+ t.match(output, /local bin folder\s*ok/, 'local bin is ok')
+ t.match(output, /global bin folder\s*ok/, 'global bin is ok')
+ t.match(output, /cache contents\s*ok/, 'cache contents is ok')
+ t.end()
+ })
+})