const t = require('tap') const requireInject = require('require-inject') const settings = { level: 'warn', } t.afterEach(cb => { Object.keys(settings).forEach(k => { delete settings[k] }) cb() }) const WARN_CALLED = [] const npmlog = { warn: (...args) => { WARN_CALLED.push(args) }, levels: { silly: -Infinity, verbose: 1000, info: 2000, timing: 2500, http: 3000, notice: 3500, warn: 4000, error: 5000, silent: Infinity, }, settings, enableColor: () => { settings.color = true }, disableColor: () => { settings.color = false }, enableUnicode: () => { settings.unicode = true }, disableUnicode: () => { settings.unicode = false }, enableProgress: () => { settings.progress = true }, disableProgress: () => { settings.progress = false }, get heading () { return settings.heading }, set heading (h) { settings.heading = h }, get level () { return settings.level }, set level (l) { settings.level = l }, } const EXPLAIN_CALLED = [] const setupLog = requireInject('../../../lib/utils/setup-log.js', { '../../../lib/utils/explain-eresolve.js': { explain: (...args) => { EXPLAIN_CALLED.push(args) return 'explanation' }, }, npmlog, }) const config = obj => ({ get (k) { return obj[k] }, set (k, v) { obj[k] = v }, }) t.test('setup with color=always and unicode', t => { npmlog.warn('ERESOLVE', 'hello', { some: 'object' }) t.strictSame(EXPLAIN_CALLED, [], 'log.warn() not patched yet') t.strictSame(WARN_CALLED, [['ERESOLVE', 'hello', { some: 'object' }]]) WARN_CALLED.length = 0 t.equal(setupLog(config({ loglevel: 'warn', color: 'always', unicode: true, progress: false, })), true) npmlog.warn('ERESOLVE', 'hello', { some: { other: 'object' } }) t.strictSame(EXPLAIN_CALLED, [[{ some: { other: 'object' } }]], 'log.warn(ERESOLVE) patched to call explainEresolve()') t.strictSame(WARN_CALLED, [ ['ERESOLVE', 'hello'], ['', 'explanation'], ], 'warn the explanation') EXPLAIN_CALLED.length = 0 WARN_CALLED.length = 0 npmlog.warn('some', 'other', 'thing') t.strictSame(EXPLAIN_CALLED, [], 'do not try to explain other things') t.strictSame(WARN_CALLED, [['some', 'other', 'thing']], 'warnings passed through') t.strictSame(settings, { level: 'warn', color: true, unicode: true, progress: false, heading: 'npm', }) t.end() }) t.test('setup with color=true, no unicode, and non-TTY terminal', t => { const { isTTY: stderrIsTTY } = process.stderr const { isTTY: stdoutIsTTY } = process.stdout t.teardown(() => { process.stderr.isTTY = stderrIsTTY process.stdout.isTTY = stdoutIsTTY }) process.stderr.isTTY = false process.stdout.isTTY = false t.equal(setupLog(config({ loglevel: 'warn', color: false, progress: false, heading: 'asdf', })), false) t.strictSame(settings, { level: 'warn', color: false, unicode: false, progress: false, heading: 'asdf', }) t.end() }) t.test('setup with color=true, no unicode, and dumb TTY terminal', t => { const { isTTY: stderrIsTTY } = process.stderr const { isTTY: stdoutIsTTY } = process.stdout const { TERM } = process.env t.teardown(() => { process.stderr.isTTY = stderrIsTTY process.stdout.isTTY = stdoutIsTTY process.env.TERM = TERM }) process.stderr.isTTY = true process.stdout.isTTY = true process.env.TERM = 'dumb' t.equal(setupLog(config({ loglevel: 'warn', color: true, progress: false, heading: 'asdf', })), true) t.strictSame(settings, { level: 'warn', color: true, unicode: false, progress: false, heading: 'asdf', }) t.end() }) t.test('setup with color=true, no unicode, and non-dumb TTY terminal', t => { const { isTTY: stderrIsTTY } = process.stderr const { isTTY: stdoutIsTTY } = process.stdout const { TERM } = process.env t.teardown(() => { process.stderr.isTTY = stderrIsTTY process.stdout.isTTY = stdoutIsTTY process.env.TERM = TERM }) process.stderr.isTTY = true process.stdout.isTTY = true process.env.TERM = 'totes not dum' t.equal(setupLog(config({ loglevel: 'warn', color: true, progress: true, heading: 'asdf', })), true) t.strictSame(settings, { level: 'warn', color: true, unicode: false, progress: true, heading: 'asdf', }) t.end() }) t.test('setup with non-TTY stdout, TTY stderr', t => { const { isTTY: stderrIsTTY } = process.stderr const { isTTY: stdoutIsTTY } = process.stdout const { TERM } = process.env t.teardown(() => { process.stderr.isTTY = stderrIsTTY process.stdout.isTTY = stdoutIsTTY process.env.TERM = TERM }) process.stderr.isTTY = true process.stdout.isTTY = false process.env.TERM = 'definitely not a dummy' t.equal(setupLog(config({ loglevel: 'warn', color: true, progress: true, heading: 'asdf', })), false) t.strictSame(settings, { level: 'warn', color: true, unicode: false, progress: true, heading: 'asdf', }) t.end() }) t.test('setup with TTY stdout, non-TTY stderr', t => { const { isTTY: stderrIsTTY } = process.stderr const { isTTY: stdoutIsTTY } = process.stdout const { TERM } = process.env t.teardown(() => { process.stderr.isTTY = stderrIsTTY process.stdout.isTTY = stdoutIsTTY process.env.TERM = TERM }) process.stderr.isTTY = false process.stdout.isTTY = true t.equal(setupLog(config({ loglevel: 'warn', color: true, progress: true, heading: 'asdf', })), true) t.strictSame(settings, { level: 'warn', color: false, unicode: false, progress: false, heading: 'asdf', }) t.end() }) t.test('set loglevel to timing', t => { setupLog(config({ timing: true, loglevel: 'notice', })) t.equal(settings.level, 'timing') t.end() }) t.test('silent has no logging', t => { const { isTTY: stderrIsTTY } = process.stderr const { isTTY: stdoutIsTTY } = process.stdout const { TERM } = process.env t.teardown(() => { process.stderr.isTTY = stderrIsTTY process.stdout.isTTY = stdoutIsTTY process.env.TERM = TERM }) process.stderr.isTTY = true process.stdout.isTTY = true process.env.TERM = 'totes not dum' setupLog(config({ loglevel: 'silent', })) t.equal(settings.progress, false, 'progress disabled when silent') t.end() })