UNPKG

morpha

Version:

A Web-IDE or Desktop-IDE creator.

263 lines (226 loc) 7.69 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); exports.default = getClientReporter; var _utils = require('../../common/utils'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function getClientReporter(ipc) { var mocha = (0, _utils.safeRequire)('mocha'); var utils = (0, _utils.safeRequire)('mocha/lib/utils'); var diff = (0, _utils.safeRequire)('diff'); var Base = mocha.reporters.Base; var color = function color(type, str) { return '\x1B[' + Base.colors[type] + 'm' + str + '\x1B[0m'; }; var objToString = Object.prototype.toString; var ClientReporter = function (_Base) { (0, _inherits3.default)(ClientReporter, _Base); function ClientReporter(runner) { (0, _classCallCheck3.default)(this, ClientReporter); var _this = (0, _possibleConstructorReturn3.default)(this, (ClientReporter.__proto__ || (0, _getPrototypeOf2.default)(ClientReporter)).call(this, runner)); function ipcListen(keys) { keys.forEach(function (key) { runner.on(key, function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } ipc.send.apply(ipc, ['mocha-reporter', key].concat(args)); }); }); } ipc.send('mocha-repoter', 'pre', runner); ipcListen(['start', 'suite', 'suite end', 'pass', 'pending', 'fail']); runner.on('end', function () { ipc.send('mocha-reporter', 'end', _this.stats, formatErrors(_this.failures)); }); return _this; } return ClientReporter; }(Base); function formatErrors(failures) { return failures.map(function (test) { // format var fmt = color('error title', ' %s) %s:\n') + color('error message', ' %s') + color('error stack', '\n%s\n'); // msg var msg = void 0; var err = test.err; var message = void 0; if (err.message && typeof err.message.toString === 'function') { message = err.message + ''; } else if (typeof err.inspect === 'function') { message = err.inspect() + ''; } else { message = ''; } var stack = err.stack || message; var index = stack.indexOf(message); var actual = err.actual; var expected = err.expected; var escape = true; if (index === -1) { msg = message; } else { index += message.length; msg = stack.slice(0, index); // remove msg from stack stack = stack.slice(index + 1); } // uncaught if (err.uncaught) { msg = 'Uncaught ' + msg; } // explicitly show diff if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) { escape = false; if (!(utils.isString(actual) && utils.isString(expected))) { err.actual = actual = utils.stringify(actual); err.expected = expected = utils.stringify(expected); } fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n'); var match = message.match(/^([^:]+): expected/); msg = '\n ' + color('error message', match ? match[1] : msg); if (Base.inlineDiffs) { msg += inlineDiff(err, escape); } else { msg += unifiedDiff(err, escape); } } // indent stack trace stack = stack.replace(/^/gm, ' '); // console.log(fmt, (i + 1), test.fullTitle(), msg, stack); return { fmt: fmt, fullTitle: test.fullTitle(), msg: msg, stack: stack }; }); } function sameType(a, b) { return objToString.call(a) === objToString.call(b); } /** * Returns an inline diff between 2 strings with coloured ANSI output * * @api private * @param {Error} err with actual/expected * @param {boolean} escape * @return {string} Diff */ function inlineDiff(err, escape) { var msg = errorDiff(err, 'WordsWithSpace', escape); // linenos var lines = msg.split('\n'); if (lines.length > 4) { var width = String(lines.length).length; msg = lines.map(function (str, i) { return pad(++i, width) + ' |' + ' ' + str; }).join('\n'); } // legend msg = '\n' + color('diff removed', 'actual') + ' ' + color('diff added', 'expected') + '\n\n' + msg + '\n'; // indent msg = msg.replace(/^/gm, ' '); return msg; } /** * Returns a unified diff between two strings. * * @api private * @param {Error} err with actual/expected * @param {boolean} escape * @return {string} The diff. */ function unifiedDiff(err, escape) { var indent = ' '; function cleanUp(line) { if (escape) { line = escapeInvisibles(line); } if (line[0] === '+') { return indent + colorLines('diff added', line); } if (line[0] === '-') { return indent + colorLines('diff removed', line); } if (line.match(/\@\@/)) { return null; } if (line.match(/\\ No newline/)) { return null; } return indent + line; } function notBlank(line) { return typeof line !== 'undefined' && line !== null; } var msg = diff.createPatch('string', err.actual, err.expected); var lines = msg.split('\n').splice(4); return '\n ' + colorLines('diff added', '+ expected') + ' ' + colorLines('diff removed', '- actual') + '\n\n' + lines.map(cleanUp).filter(notBlank).join('\n'); } /** * Return a character diff for `err`. * * @api private * @param {Error} err * @param {string} type * @param {boolean} escape * @return {string} */ function errorDiff(err, type, escape) { var actual = escape ? escapeInvisibles(err.actual) : err.actual; var expected = escape ? escapeInvisibles(err.expected) : err.expected; return diff['diff' + type](actual, expected).map(function (str) { if (str.added) { return colorLines('diff added', str.value); } if (str.removed) { return colorLines('diff removed', str.value); } return str.value; }).join(''); } /** * Returns a string with all invisible characters in plain text * * @api private * @param {string} line * @return {string} */ function escapeInvisibles(line) { return line.replace(/\t/g, '<tab>').replace(/\r/g, '<CR>').replace(/\n/g, '<LF>\n'); } /** * Color lines for `str`, using the color `name`. * @param {string} name * @param {string} str * @return {string} */ function colorLines(name, str) { return str.split('\n').map(function (str) { return color(name, str); }).join('\n'); } /** * Pad the given `str` to `len`. * * @api private * @param {string} str * @param {string} len * @return {string} */ function pad(str, len) { str = String(str); return Array(len - str.length + 1).join(' ') + str; } return ClientReporter; }