UNPKG

console-testing-library

Version:
256 lines (207 loc) 7.15 kB
"use strict"; exports.__esModule = true; exports.createConsole = createConsole; exports.mockConsole = mockConsole; exports.getLog = getLog; exports.silenceConsole = silenceConsole; exports.restore = restore; var _console = require("console"); var _stream = require("stream"); var _util = _interopRequireDefault(require("util")); var _jestSnapshot = require("jest-snapshot"); var _prettyFormat = _interopRequireDefault(require("pretty-format")); var _stripAnsi = _interopRequireDefault(require("strip-ansi")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const INSPECT_SYMBOL = _util.default.inspect.custom; const instances = new WeakMap(); const LEVELS = { log: ['log', 'trace', 'dir', 'dirxml', 'group', 'groupCollapsed', 'debug', 'timeLog'], info: ['count', 'info', 'timeEnd'], warn: ['warn', 'countReset'], error: ['error', 'assert'] }; function createConsole({ isSilent: defaultIsSilent = true, stripAnsi: defaultStripAnsi = false } = {}) { let logs = []; let records = {}; let levels = { log: '', info: '', warn: '', error: '' }; let currentLevel = undefined; let currentMethod = undefined; let isSilent = defaultIsSilent; let stripAnsi = defaultStripAnsi; let targetConsole = undefined; const stringifyLogs = logs => { return logs.map(log => log[1]).join('\n'); }; const writable = new _stream.Writable({ write(chunk, encoding, callback) { const message = chunk.toString('utf8') // Strip out the new line character in the end .slice(0, -1); const normalizedMessage = stripAnsi ? (0, _stripAnsi.default)(message) : message; logs.push([currentLevel, normalizedMessage]); if (currentLevel && currentLevel in levels) { levels[currentLevel] = [levels[currentLevel], normalizedMessage].filter(Boolean).join('\n'); } records[currentMethod] = [records[currentMethod], normalizedMessage].filter(Boolean).join('\n'); callback(); } }); const testingConsole = new _console.Console(writable, writable); testingConsole.clear = function clear() { logs = []; records = {}; levels = { log: '', info: '', warn: '', error: '' }; currentLevel = undefined; currentMethod = undefined; }; Object.getOwnPropertyNames(testingConsole).forEach(property => { if (typeof testingConsole[property] === 'function' && // Internal properties like `_stdoutErrorHandler` and `_stderrErrorHandler` !property.startsWith('_')) { if (property !== 'clear') { const originalFunction = testingConsole[property]; testingConsole[property] = function (...args) { currentLevel = undefined; currentMethod = property; Object.keys(LEVELS).forEach(level => { if (LEVELS[level].includes(property)) { currentLevel = level; } }); const prettiedArguments = args.map(argv => { if ((typeof argv === 'object' || typeof argv === 'function') && argv !== null) { // We return an object with inspect symbol here because string substitutions requires objects return { [INSPECT_SYMBOL]: () => (0, _prettyFormat.default)(argv) }; } return argv; }); const returnValue = originalFunction.apply(this, prettiedArguments); if (!isSilent && targetConsole) { targetConsole[property].apply(this, args); } return returnValue; }; } Object.defineProperty(testingConsole[property], 'name', { value: property }); testingConsole[property].testingConsole = testingConsole; if (typeof jest === 'object' && typeof jest.spyOn === 'function') { jest.spyOn(testingConsole, property); Object.defineProperty(testingConsole[property], 'name', { value: property }); testingConsole[property].testingConsole = testingConsole; } } }); instances.set(testingConsole, { get log() { return stringifyLogs(logs); }, get logs() { return logs; }, levels: { get log() { return levels.log; }, get info() { return levels.info; }, get warn() { return levels.warn; }, get error() { return levels.error; } }, get stderr() { return stringifyLogs(logs.filter(([logLevel]) => ['warn', 'error'].includes(logLevel))); }, get stdout() { return stringifyLogs(logs.filter(([logLevel]) => ['log', 'info'].includes(logLevel))); }, getRecord(method) { return records[method] || ''; }, get silence() { return isSilent; }, set silence(shouldSilent = true) { isSilent = !!shouldSilent; }, get _targetConsole() { return targetConsole; }, set _targetConsole(target) { targetConsole = target; } }); return testingConsole; } function mockConsole(testingConsole, targetConsoleParent = global, targetConsoleKey = 'console') { const targetConsole = targetConsoleParent[targetConsoleKey]; targetConsoleParent[targetConsoleKey] = testingConsole; const instance = instances.get(testingConsole); instance._targetConsole = targetConsole; return () => { targetConsoleParent[targetConsoleKey] = targetConsole; instance._targetConsole = undefined; }; } function getLog(testingConsole = global.console) { return instances.get(testingConsole); } function silenceConsole(testingConsole = global.console, shouldSilent = true) { if (typeof arguments[0] === 'boolean') { testingConsole = global.console; shouldSilent = arguments[0]; } instances.get(testingConsole).silence = !!shouldSilent; } function restore() { global.console = global.originalConsole; } if (typeof expect === 'function' && typeof expect.extend === 'function') { expect.extend({ toMatchInlineSnapshot(received, ...args) { /* ------- Workaround for custom inline snapshot matchers ------- */ const error = new Error(); const stacks = error.stack.split('\n'); for (let i = 1; i < stacks.length; i += 1) { if (stacks[i].includes(__filename)) { stacks.splice(1, i); break; } } error.stack = stacks.join('\n'); const context = Object.assign(this, { error }); /* -------------------------------------------------------------- */ const testingConsoleInstance = received && received.testingConsole || received; if (!testingConsoleInstance || !instances.has(testingConsoleInstance)) { return _jestSnapshot.toMatchInlineSnapshot.call(context, received, ...args); } if (typeof received === 'function') { return _jestSnapshot.toMatchInlineSnapshot.call(context, getLog().getRecord(received.name), ...args); } else if (typeof received === 'object') { return _jestSnapshot.toMatchInlineSnapshot.call(context, getLog(received).log, ...args); } } }); }