diff options
author | nlf <quitlahok@gmail.com> | 2020-12-10 20:45:46 +0300 |
---|---|---|
committer | isaacs <i@izs.me> | 2020-12-11 22:33:16 +0300 |
commit | 7a4f0c96c2ab9f264f7bda2caf7e72c881571270 (patch) | |
tree | 78f820f3372bc87ae10ae43cc27debb4488b1183 /test | |
parent | d825e901eceea4cf8d860e35238dc30008eb4da4 (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.js | 943 |
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() + }) +}) |