diff --git a/test/lib/doctor.js b/test/lib/doctor.js index db41fc8e5dd56..f5e6fd062a331 100644 --- a/test/lib/doctor.js +++ b/test/lib/doctor.js @@ -22,6 +22,13 @@ const ping = async () => { throw pingError } +let whichError = null +const which = async () => { + if (whichError) + throw whichError + return '/path/to/git' +} + const nodeVersions = [ { version: 'v14.0.0', lts: false }, { version: 'v13.0.0', lts: false }, @@ -106,13 +113,6 @@ const pacote = { }, } -let whichError = null -const which = async () => { - if (whichError) - throw whichError - return '/path/to/git' -} - let verifyResponse = { verifiedCount: 1, verifiedContent: 1 } const cacache = { verify: async () => { @@ -133,811 +133,837 @@ const doctor = requireInject('../../lib/doctor.js', { 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() +const origVersion = process.version +test('node versions', t => { + t.plan(nodeVersions.length) + + nodeVersions.forEach(({ version }) => { + t.test(`${version}:`, vt => { + Object.defineProperty(process, 'version', { value: version }) + vt.teardown(() => { + Object.defineProperty(process, 'version', { value: origVersion }) + }) + + vt.test(`${version}: npm doctor checks ok`, st => { + const dir = st.testdir() + npm.cache = npm.flatOptions.cache = dir + npm.localDir = dir + npm.globalDir = dir + npm.localBin = dir + npm.globalBin = dir + + st.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) { + st.fail(output) + return st.end() + } + + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: { finished: true }, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.match(output, /npm ping\s*ok/, 'ping output is ok') + st.match(output, /npm -v\s*ok/, 'npm -v output is ok') + st.match(output, /node -v\s*ok/, 'node -v output is ok') + st.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok') + st.match(output, /which git\s*ok/, 'which git output is ok') + st.match(output, /cached files\s*ok/, 'cached files are ok') + st.match(output, /local node_modules\s*ok/, 'local node_modules are ok') + st.match(output, /global node_modules\s*ok/, 'global node_modules are ok') + st.match(output, /local bin folder\s*ok/, 'local bin is ok') + st.match(output, /global bin folder\s*ok/, 'global bin is ok') + st.match(output, /cache contents\s*ok/, 'cache contents is ok') + st.end() + }) + }) + + vt.test('npm doctor supports silent', st => { + const dir = st.testdir() + npm.cache = npm.flatOptions.cache = dir + npm.localDir = dir + npm.globalDir = dir + npm.localBin = dir + npm.globalBin = dir + npm.log.level = 'info' + + st.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) { + st.fail(err) + return st.end() + } + + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: { finished: true }, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.strictSame(output, [], 'did not print output') + st.end() + }) + }) + + vt.test('npm doctor supports color', st => { + const dir = st.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 = () => {} + + st.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) => { + st.match(err, /Some problems found/, 'detected the ping error') + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: { finished: true }, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.match(output, /npm ping.*not ok/, 'ping output is ok') + st.match(output, /npm -v.*ok/, 'npm -v output is ok') + st.match(output, /node -v.*ok/, 'node -v output is ok') + st.match(output, /npm config get registry.*ok.*using default/, 'npm config get registry output is ok') + st.match(output, /which git.*ok/, 'which git output is ok') + st.match(output, /cached files.*ok/, 'cached files are ok') + st.match(output, /local node_modules.*ok/, 'local node_modules are ok') + st.match(output, /global node_modules.*ok/, 'global node_modules are ok') + st.match(output, /local bin folder.*ok/, 'local bin is ok') + st.match(output, /global bin folder.*ok/, 'global bin is ok') + st.match(output, /cache contents.*ok/, 'cache contents is ok') + st.notEqual(output[0], ansiTrim(output[0]), 'output should contain color codes') + st.end() + }) + }) + + vt.test('npm doctor skips some tests in windows', st => { + 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 = st.testdir() + npm.cache = npm.flatOptions.cache = dir + npm.localDir = dir + npm.globalDir = dir + npm.localBin = dir + npm.globalBin = dir + + st.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) { + st.fail(output) + return st.end() + } + + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: undefined, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.match(output, /npm ping\s*ok/, 'ping output is ok') + st.match(output, /npm -v\s*ok/, 'npm -v output is ok') + st.match(output, /node -v\s*ok/, 'node -v output is ok') + st.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok') + st.match(output, /which git\s*ok/, 'which git output is ok') + st.match(output, /cache contents\s*ok/, 'cache contents is ok') + st.end() + }) + }) + + vt.test('npm doctor ping error E{3}', st => { + const dir = st.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 = () => {} + + st.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) => { + st.match(err, /Some problems found/, 'detected the ping error') + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: { finished: true }, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.match(output, /npm ping\s*not ok\s*111 this error is 111/, 'ping output contains trimmed error') + st.match(output, /npm -v\s*ok/, 'npm -v output is ok') + st.match(output, /node -v\s*ok/, 'node -v output is ok') + st.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok') + st.match(output, /which git\s*ok/, 'which git output is ok') + st.match(output, /cached files\s*ok/, 'cached files are ok') + st.match(output, /local node_modules\s*ok/, 'local node_modules are ok') + st.match(output, /global node_modules\s*ok/, 'global node_modules are ok') + st.match(output, /local bin folder\s*ok/, 'local bin is ok') + st.match(output, /global bin folder\s*ok/, 'global bin is ok') + st.match(output, /cache contents\s*ok/, 'cache contents is ok') + st.end() + }) + }) + + vt.test('npm doctor generic ping error', st => { + const dir = st.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 = () => {} + + st.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) => { + st.match(err, /Some problems found/, 'detected the ping error') + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: { finished: true }, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.match(output, /npm ping\s*not ok\s*generic error/, 'ping output contains trimmed error') + st.match(output, /npm -v\s*ok/, 'npm -v output is ok') + st.match(output, /node -v\s*ok/, 'node -v output is ok') + st.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok') + st.match(output, /which git\s*ok/, 'which git output is ok') + st.match(output, /cached files\s*ok/, 'cached files are ok') + st.match(output, /local node_modules\s*ok/, 'local node_modules are ok') + st.match(output, /global node_modules\s*ok/, 'global node_modules are ok') + st.match(output, /local bin folder\s*ok/, 'local bin is ok') + st.match(output, /global bin folder\s*ok/, 'global bin is ok') + st.match(output, /cache contents\s*ok/, 'cache contents is ok') + st.end() + }) + }) + + vt.test('npm doctor outdated npm version', st => { + const dir = st.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 = () => {} + + st.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) => { + st.match(err, /Some problems found/, 'detected the out of date npm') + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: { finished: true }, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.match(output, /npm ping\s*ok/, 'ping output is ok') + st.match(output, /npm -v\s*not ok/, 'npm -v output is not ok') + st.match(output, /node -v\s*ok/, 'node -v output is ok') + st.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok') + st.match(output, /which git\s*ok/, 'which git output is ok') + st.match(output, /cached files\s*ok/, 'cached files are ok') + st.match(output, /local node_modules\s*ok/, 'local node_modules are ok') + st.match(output, /global node_modules\s*ok/, 'global node_modules are ok') + st.match(output, /local bin folder\s*ok/, 'local bin is ok') + st.match(output, /global bin folder\s*ok/, 'global bin is ok') + st.match(output, /cache contents\s*ok/, 'cache contents is ok') + st.end() + }) + }) + + vt.test('npm doctor file permission checks', st => { + const dir = st.testdir({ + cache: { + one: 'one', + link: st.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 = () => {} + + st.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) => { + st.match(err, /Some problems found/, 'identified problems') + st.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') + st.match(output, /npm ping\s*ok/, 'ping output is ok') + st.match(output, /npm -v\s*ok/, 'npm -v output is ok') + st.match(output, /node -v\s*ok/, 'node -v output is ok') + st.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok') + st.match(output, /which git\s*ok/, 'which git output is ok') + st.match(output, /cached files\s*not ok/, 'cached files are not ok') + st.match(output, /local node_modules\s*not ok/, 'local node_modules are not ok') + st.match(output, /global node_modules\s*not ok/, 'global node_modules are not ok') + st.match(output, /local bin folder\s*not ok/, 'local bin is not ok') + st.match(output, /global bin folder\s*not ok/, 'global bin is not ok') + st.match(output, /cache contents\s*ok/, 'cache contents is ok') + st.end() + }) + }) + + vt.test('npm doctor missing git', st => { + const dir = st.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 = () => {} + + st.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) => { + st.match(err, /Some problems found/, 'detected the missing git') + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: { finished: true }, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.match(output, /npm ping\s*ok/, 'ping output is ok') + st.match(output, /npm -v\s*ok/, 'npm -v output is ok') + st.match(output, /node -v\s*ok/, 'node -v output is ok') + st.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok') + st.match(output, /which git\s*not ok/, 'which git output is not ok') + st.match(output, /cached files\s*ok/, 'cached files are ok') + st.match(output, /local node_modules\s*ok/, 'local node_modules are ok') + st.match(output, /global node_modules\s*ok/, 'global node_modules are ok') + st.match(output, /local bin folder\s*ok/, 'local bin is ok') + st.match(output, /global bin folder\s*ok/, 'global bin is ok') + st.match(output, /cache contents\s*ok/, 'cache contents is ok') + st.end() + }) + }) + + vt.test('npm doctor cache verification showed bad content', st => { + const dir = st.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 = () => {} + + st.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) { + st.fail(output) + return st.end() + } + + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: { finished: true }, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.match(output, /npm ping\s*ok/, 'ping output is ok') + st.match(output, /npm -v\s*ok/, 'npm -v output is ok') + st.match(output, /node -v\s*ok/, 'node -v output is ok') + st.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok') + st.match(output, /which git\s*ok/, 'which git output is ok') + st.match(output, /cached files\s*ok/, 'cached files are ok') + st.match(output, /local node_modules\s*ok/, 'local node_modules are ok') + st.match(output, /global node_modules\s*ok/, 'global node_modules are ok') + st.match(output, /local bin folder\s*ok/, 'local bin is ok') + st.match(output, /global bin folder\s*ok/, 'global bin is ok') + st.match(output, /cache contents\s*ok/, 'cache contents is not ok') + st.end() + }) + }) + + vt.test('npm doctor cache verification showed reclaimed content', st => { + const dir = st.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 = () => {} + + st.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) { + st.fail(output) + return st.end() + } + + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: { finished: true }, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.match(output, /npm ping\s*ok/, 'ping output is ok') + st.match(output, /npm -v\s*ok/, 'npm -v output is ok') + st.match(output, /node -v\s*ok/, 'node -v output is ok') + st.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok') + st.match(output, /which git\s*ok/, 'which git output is ok') + st.match(output, /cached files\s*ok/, 'cached files are ok') + st.match(output, /local node_modules\s*ok/, 'local node_modules are ok') + st.match(output, /global node_modules\s*ok/, 'global node_modules are ok') + st.match(output, /local bin folder\s*ok/, 'local bin is ok') + st.match(output, /global bin folder\s*ok/, 'global bin is ok') + st.match(output, /cache contents\s*ok/, 'cache contents is not ok') + st.end() + }) + }) + + vt.test('npm doctor cache verification showed missing content', st => { + 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 = () => {} + + st.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) { + st.fail(output) + return st.end() + } + + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: { finished: true }, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.match(output, /npm ping\s*ok/, 'ping output is ok') + st.match(output, /npm -v\s*ok/, 'npm -v output is ok') + st.match(output, /node -v\s*ok/, 'node -v output is ok') + st.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok') + st.match(output, /which git\s*ok/, 'which git output is ok') + st.match(output, /cached files\s*ok/, 'cached files are ok') + st.match(output, /local node_modules\s*ok/, 'local node_modules are ok') + st.match(output, /global node_modules\s*ok/, 'global node_modules are ok') + st.match(output, /local bin folder\s*ok/, 'local bin is ok') + st.match(output, /global bin folder\s*ok/, 'global bin is ok') + st.match(output, /cache contents\s*ok/, 'cache contents is not ok') + st.end() + }) + }) + + vt.test('npm doctor not using default registry', st => { + const dir = st.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 = () => {} + + st.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 + st.match(err, /Some problems found/, 'detected the non-default registry') + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: { finished: true }, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.match(output, /npm ping\s*ok/, 'ping output is ok') + st.match(output, /npm -v\s*ok/, 'npm -v output is ok') + st.match(output, /node -v\s*ok/, 'node -v output is ok') + st.match(output, /npm config get registry\s*not ok/, 'npm config get registry output is not ok') + st.match(output, /which git\s*ok/, 'which git output is ok') + st.match(output, /cached files\s*ok/, 'cached files are ok') + st.match(output, /local node_modules\s*ok/, 'local node_modules are ok') + st.match(output, /global node_modules\s*ok/, 'global node_modules are ok') + st.match(output, /local bin folder\s*ok/, 'local bin is ok') + st.match(output, /global bin folder\s*ok/, 'global bin is ok') + st.match(output, /cache contents\s*ok/, 'cache contents is ok') + st.end() + }) + }) + + vt.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('outdated node version', vt => { + vt.plan(1) + const version = 'v10.0.0' -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() + Object.defineProperty(process, 'version', { value: version }) + vt.teardown(() => { + Object.defineProperty(process, 'version', { value: origVersion }) }) - 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() + vt.test('npm doctor outdated nodejs version', st => { + const dir = st.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 = () => {} + + st.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) => { + st.match(err, /Some problems found/, 'detected the out of date nodejs') + st.match(logs, { + checkPing: { finished: true }, + getLatestNpmVersion: { finished: true }, + getLatestNodejsVersion: { finished: true }, + getGitPath: { finished: true }, + [dir]: { finished: true }, + verifyCachedFiles: { finished: true }, + }, 'trackers all finished') + st.match(output, /npm ping\s*ok/, 'ping output is ok') + st.match(output, /npm -v\s*ok/, 'npm -v output is ok') + st.match(output, /node -v\s*not ok/, 'node -v output is not ok') + st.match(output, /npm config get registry\s*ok\s*using default/, 'npm config get registry output is ok') + st.match(output, /which git\s*ok/, 'which git output is ok') + st.match(output, /cached files\s*ok/, 'cached files are ok') + st.match(output, /local node_modules\s*ok/, 'local node_modules are ok') + st.match(output, /global node_modules\s*ok/, 'global node_modules are ok') + st.match(output, /local bin folder\s*ok/, 'local bin is ok') + st.match(output, /global bin folder\s*ok/, 'global bin is ok') + st.match(output, /cache contents\s*ok/, 'cache contents is ok') + st.end() + }) }) })