Files
taimed/node_modules/js-reporters/dist/js-reporters.js
2025-07-24 17:21:45 +08:00

1685 lines
46 KiB
JavaScript

/**
* JsReporters 1.2.1
* https://github.com/js-reporters
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
* Date: Tue Jul 04 2017
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.JsReporters = factory());
}(this, (function () { 'use strict';
function interopDefault(ex) {
return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex;
}
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
var asyncGenerator = function () {
function AwaitValue(value) {
this.value = value;
}
function AsyncGenerator(gen) {
var front, back;
function send(key, arg) {
return new Promise(function (resolve, reject) {
var request = {
key: key,
arg: arg,
resolve: resolve,
reject: reject,
next: null
};
if (back) {
back = back.next = request;
} else {
front = back = request;
resume(key, arg);
}
});
}
function resume(key, arg) {
try {
var result = gen[key](arg);
var value = result.value;
if (value instanceof AwaitValue) {
Promise.resolve(value.value).then(function (arg) {
resume("next", arg);
}, function (arg) {
resume("throw", arg);
});
} else {
settle(result.done ? "return" : "normal", result.value);
}
} catch (err) {
settle("throw", err);
}
}
function settle(type, value) {
switch (type) {
case "return":
front.resolve({
value: value,
done: true
});
break;
case "throw":
front.reject(value);
break;
default:
front.resolve({
value: value,
done: false
});
break;
}
front = front.next;
if (front) {
resume(front.key, front.arg);
} else {
back = null;
}
}
this._invoke = send;
if (typeof gen.return !== "function") {
this.return = undefined;
}
}
if (typeof Symbol === "function" && Symbol.asyncIterator) {
AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
return this;
};
}
AsyncGenerator.prototype.next = function (arg) {
return this._invoke("next", arg);
};
AsyncGenerator.prototype.throw = function (arg) {
return this._invoke("throw", arg);
};
AsyncGenerator.prototype.return = function (arg) {
return this._invoke("return", arg);
};
return {
wrap: function (fn) {
return function () {
return new AsyncGenerator(fn.apply(this, arguments));
};
},
await: function (value) {
return new AwaitValue(value);
}
};
}();
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
var events = createCommonjsModule(function (module) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
function EventEmitter() {
this._events = this._events || {};
this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
EventEmitter.defaultMaxListeners = 10;
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function (n) {
if (!isNumber(n) || n < 0 || isNaN(n)) throw TypeError('n must be a positive number');
this._maxListeners = n;
return this;
};
EventEmitter.prototype.emit = function (type) {
var er, handler, len, args, i, listeners;
if (!this._events) this._events = {};
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events.error || isObject(this._events.error) && !this._events.error.length) {
er = arguments[1];
if (er instanceof Error) {
throw er; // Unhandled 'error' event
} else {
// At least give some kind of context to the user
var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
err.context = er;
throw err;
}
}
}
handler = this._events[type];
if (isUndefined(handler)) return false;
if (isFunction(handler)) {
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
args = Array.prototype.slice.call(arguments, 1);
handler.apply(this, args);
}
} else if (isObject(handler)) {
args = Array.prototype.slice.call(arguments, 1);
listeners = handler.slice();
len = listeners.length;
for (i = 0; i < len; i++) {
listeners[i].apply(this, args);
}
}
return true;
};
EventEmitter.prototype.addListener = function (type, listener) {
var m;
if (!isFunction(listener)) throw TypeError('listener must be a function');
if (!this._events) this._events = {};
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (this._events.newListener) this.emit('newListener', type, isFunction(listener.listener) ? listener.listener : listener);
if (!this._events[type])
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;else if (isObject(this._events[type]))
// If we've already got an array, just append.
this._events[type].push(listener);else
// Adding the second element, need to change to array.
this._events[type] = [this._events[type], listener];
// Check for listener leak
if (isObject(this._events[type]) && !this._events[type].warned) {
if (!isUndefined(this._maxListeners)) {
m = this._maxListeners;
} else {
m = EventEmitter.defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length);
if (typeof console.trace === 'function') {
// not supported in IE 10
console.trace();
}
}
}
return this;
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.once = function (type, listener) {
if (!isFunction(listener)) throw TypeError('listener must be a function');
var fired = false;
function g() {
this.removeListener(type, g);
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
}
g.listener = listener;
this.on(type, g);
return this;
};
// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener = function (type, listener) {
var list, position, length, i;
if (!isFunction(listener)) throw TypeError('listener must be a function');
if (!this._events || !this._events[type]) return this;
list = this._events[type];
length = list.length;
position = -1;
if (list === listener || isFunction(list.listener) && list.listener === listener) {
delete this._events[type];
if (this._events.removeListener) this.emit('removeListener', type, listener);
} else if (isObject(list)) {
for (i = length; i-- > 0;) {
if (list[i] === listener || list[i].listener && list[i].listener === listener) {
position = i;
break;
}
}
if (position < 0) return this;
if (list.length === 1) {
list.length = 0;
delete this._events[type];
} else {
list.splice(position, 1);
}
if (this._events.removeListener) this.emit('removeListener', type, listener);
}
return this;
};
EventEmitter.prototype.removeAllListeners = function (type) {
var key, listeners;
if (!this._events) return this;
// not listening for removeListener, no need to emit
if (!this._events.removeListener) {
if (arguments.length === 0) this._events = {};else if (this._events[type]) delete this._events[type];
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
for (key in this._events) {
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = {};
return this;
}
listeners = this._events[type];
if (isFunction(listeners)) {
this.removeListener(type, listeners);
} else if (listeners) {
// LIFO order
while (listeners.length) {
this.removeListener(type, listeners[listeners.length - 1]);
}
}
delete this._events[type];
return this;
};
EventEmitter.prototype.listeners = function (type) {
var ret;
if (!this._events || !this._events[type]) ret = [];else if (isFunction(this._events[type])) ret = [this._events[type]];else ret = this._events[type].slice();
return ret;
};
EventEmitter.prototype.listenerCount = function (type) {
if (this._events) {
var evlistener = this._events[type];
if (isFunction(evlistener)) return 1;else if (evlistener) return evlistener.length;
}
return 0;
};
EventEmitter.listenerCount = function (emitter, type) {
return emitter.listenerCount(type);
};
function isFunction(arg) {
return typeof arg === 'function';
}
function isNumber(arg) {
return typeof arg === 'number';
}
function isObject(arg) {
return (typeof arg === 'undefined' ? 'undefined' : _typeof(arg)) === 'object' && arg !== null;
}
function isUndefined(arg) {
return arg === void 0;
}
});
var EventEmitter = interopDefault(events);
function getAllTests(suite) {
var childSuiteTests = suite.childSuites.map(function (childSuite) {
return getAllTests(childSuite);
}).reduce(function (allTests, a) {
return allTests.concat(a);
}, []);
return suite.tests.concat(childSuiteTests);
}
function getRuntime(suite) {
if (suite.status === 'skipped' || suite.status === undefined) {
return undefined;
}
return getAllTests(suite).map(function (test) {
return test.status === 'skipped' ? 0 : test.runtime;
}).reduce(function (sum, testRuntime) {
return sum + testRuntime;
}, 0);
}
function getStatus(suite) {
var passed = 0;
var failed = 0;
var skipped = 0;
var todo = 0;
var tests = getAllTests(suite);
for (var i = 0; i < tests.length; i++) {
var test = tests[i];
// If a suite contains a test whose status is still undefined,
// there is no final status for the suite as well.
if (test.status === undefined) {
return undefined;
} else if (test.status === 'passed') {
passed++;
} else if (test.status === 'skipped') {
skipped++;
} else if (test.status === 'todo') {
todo++;
} else {
failed++;
}
}
if (failed > 0) {
return 'failed';
} else if (skipped > 0 && passed === 0) {
return 'skipped';
} else if (todo > 0 && passed === 0) {
return 'todo';
} else {
return 'passed';
}
}
function getSuiteStartTestCounts(suite) {
var tests = getAllTests(suite);
return {
total: tests.length
};
}
function getSuiteEndTestCounts(suite) {
var tests = getAllTests(suite);
return {
passed: tests.filter(function (test) {
return test.status === 'passed';
}).length,
failed: tests.filter(function (test) {
return test.status === 'failed';
}).length,
skipped: tests.filter(function (test) {
return test.status === 'skipped';
}).length,
todo: tests.filter(function (test) {
return test.status === 'todo';
}).length,
total: tests.length
};
}
var Assertion =
/**
* @param {Boolean} passed
* @param {*} actual
* @param {*} expected
* @param {String} message
* @param {String|undefined} stack
* @param {Boolean} todo
*/
function Assertion(passed, actual, expected, message, stack, todo) {
classCallCheck(this, Assertion);
this.passed = passed;
this.actual = actual;
this.expected = expected;
this.message = message;
this.stack = stack;
this.todo = todo;
};
var TestStart =
/**
* @param {String} name
* @param {String} suiteName
* @param {String[]} fullName
*/
function TestStart(name, suiteName, fullName) {
classCallCheck(this, TestStart);
this.name = name;
this.suiteName = suiteName;
this.fullName = fullName;
};
var TestEnd =
/**
* @param {String} name
* @param {String} suiteName
* @param {String[]} fullName
* @param {String} status
* @param {Number} runtime
* @param {Assertion[]} errors
* @param {Assertion[]} assertions
*/
function TestEnd(name, suiteName, fullName, status, runtime, errors, assertions) {
classCallCheck(this, TestEnd);
this.name = name;
this.suiteName = suiteName;
this.fullName = fullName;
this.status = status;
this.runtime = runtime;
this.errors = errors;
this.assertions = assertions;
};
var SuiteStart =
/**
* @param {String} name
* @param {String[]} fullName
* @param {Test[]} tests
* @param {Suite[]} childSuites
*/
function SuiteStart(name, fullName, tests, childSuites, testCounts) {
classCallCheck(this, SuiteStart);
this.name = name;
this.fullName = fullName;
this.tests = tests;
this.childSuites = childSuites;
this.testCounts = getSuiteStartTestCounts(this);
};
var SuiteEnd =
/**
* @param {String} name
* @param {String[]} fullName
* @param {Test[]} tests
* @param {Suite[]} childSuites
* @param {String} status
* @param {Object} testCounts
* @param {Number} testCounts.passed
* @param {Number} testCounts.failed
* @param {Number} testCounts.skipped
* @param {Number} testCounts.total
* @param {Number} runtime
*/
function SuiteEnd(name, fullName, tests, childSuites, status, testCounts, runtime) {
classCallCheck(this, SuiteEnd);
this.name = name;
this.fullName = fullName;
this.tests = tests;
this.childSuites = childSuites;
this.status = status || getStatus(this);
this.testCounts = testCounts || getSuiteEndTestCounts(this);
this.runtime = runtime || getRuntime(this);
};
var MochaAdapter = function (_EventEmitter) {
inherits(MochaAdapter, _EventEmitter);
function MochaAdapter(mocha) {
classCallCheck(this, MochaAdapter);
var _this = possibleConstructorReturn(this, (MochaAdapter.__proto__ || Object.getPrototypeOf(MochaAdapter)).call(this));
_this.mocha = mocha;
_this.origReporter = mocha._reporter;
mocha.reporter(function (runner) {
_this.runner = runner;
// eslint-disable-next-line no-unused-vars
var origReporterInstance = new (_this.origReporter.bind(_this.mocha, _this.runner))();
runner.on('start', _this.onStart.bind(_this));
runner.on('suite', _this.onSuite.bind(_this));
runner.on('test', _this.onTest.bind(_this));
runner.on('pending', _this.onPending.bind(_this));
runner.on('fail', _this.onFail.bind(_this));
runner.on('test end', _this.onTestEnd.bind(_this));
runner.on('suite end', _this.onSuiteEnd.bind(_this));
runner.on('end', _this.onEnd.bind(_this));
});
return _this;
}
createClass(MochaAdapter, [{
key: 'convertToSuiteStart',
value: function convertToSuiteStart(mochaSuite) {
return new SuiteStart(mochaSuite.title, this.buildSuiteFullName(mochaSuite), mochaSuite.tests.map(this.convertTest.bind(this)), mochaSuite.suites.map(this.convertToSuiteStart.bind(this)));
}
}, {
key: 'convertToSuiteEnd',
value: function convertToSuiteEnd(mochaSuite) {
return new SuiteEnd(mochaSuite.title, this.buildSuiteFullName(mochaSuite), mochaSuite.tests.map(this.convertTest.bind(this)), mochaSuite.suites.map(this.convertToSuiteEnd.bind(this)));
}
}, {
key: 'convertTest',
value: function convertTest(mochaTest) {
var suiteName;
var fullName;
if (!mochaTest.parent.root) {
suiteName = mochaTest.parent.title;
fullName = this.buildSuiteFullName(mochaTest.parent);
// Add also the test name.
fullName.push(mochaTest.title);
} else {
fullName = [mochaTest.title];
}
// If the test has the errors attached a "test end" must be emitted, else
// a "test start".
if (mochaTest.errors !== undefined) {
var status = mochaTest.state === undefined ? 'skipped' : mochaTest.state;
var errors = [];
mochaTest.errors.forEach(function (error) {
errors.push(new Assertion(false, error.actual, error.expected, error.message || error.toString(), error.stack));
});
// Test end, for the assertions property pass an empty array.
return new TestEnd(mochaTest.title, suiteName, fullName, status, mochaTest.duration, errors, errors);
}
// Test start.
return new TestStart(mochaTest.title, suiteName, fullName);
}
/**
* Builds an array with the names of nested suites.
*/
}, {
key: 'buildSuiteFullName',
value: function buildSuiteFullName(mochaSuite) {
var fullName = [];
var parent = mochaSuite.parent;
if (!mochaSuite.root) {
fullName.push(mochaSuite.title);
}
while (parent && !parent.root) {
fullName.unshift(parent.title);
parent = parent.parent;
}
return fullName;
}
}, {
key: 'onStart',
value: function onStart() {
var globalSuiteStart = this.convertToSuiteStart(this.runner.suite);
globalSuiteStart.name = undefined;
this.emit('runStart', globalSuiteStart);
}
}, {
key: 'onSuite',
value: function onSuite(mochaSuite) {
if (!mochaSuite.root) {
this.emit('suiteStart', this.convertToSuiteStart(mochaSuite));
}
}
}, {
key: 'onTest',
value: function onTest(mochaTest) {
this.errors = [];
this.emit('testStart', this.convertTest(mochaTest));
}
/**
* Emits the start of pending tests, because Mocha does not emit skipped tests
* on its "test" event.
*/
}, {
key: 'onPending',
value: function onPending(mochaTest) {
this.emit('testStart', this.convertTest(mochaTest));
}
}, {
key: 'onFail',
value: function onFail(test, error) {
this.errors.push(error);
}
}, {
key: 'onTestEnd',
value: function onTestEnd(mochaTest) {
// Save the errors on Mocha's test object, because when the suite that
// contains this test is emitted on the "suiteEnd" event, it should contain
// also this test with all its details (errors, status, runtime). Runtime
// and status are already attached to the test, but the errors don't.
mochaTest.errors = this.errors;
this.emit('testEnd', this.convertTest(mochaTest));
}
}, {
key: 'onSuiteEnd',
value: function onSuiteEnd(mochaSuite) {
if (!mochaSuite.root) {
this.emit('suiteEnd', this.convertToSuiteEnd(mochaSuite));
}
}
}, {
key: 'onEnd',
value: function onEnd() {
var globalSuiteEnd = this.convertToSuiteEnd(this.runner.suite);
globalSuiteEnd.name = undefined;
this.emit('runEnd', globalSuiteEnd);
}
}]);
return MochaAdapter;
}(EventEmitter);
/**
* Limitations:
* - Errors in afterAll are ignored.
*/
var JasmineAdapter = function (_EventEmitter) {
inherits(JasmineAdapter, _EventEmitter);
function JasmineAdapter(jasmine) {
classCallCheck(this, JasmineAdapter);
var _this = possibleConstructorReturn(this, (JasmineAdapter.__proto__ || Object.getPrototypeOf(JasmineAdapter)).call(this));
_this.jasmine = jasmine;
// NodeJS/browser
_this.env = jasmine.env || jasmine.getEnv();
_this.suites = {};
_this.tests = {};
var reporter = {
jasmineStarted: _this.onJasmineStarted.bind(_this),
specDone: _this.onSpecDone.bind(_this),
specStarted: _this.onSpecStarted.bind(_this),
suiteStarted: _this.onSuiteStarted.bind(_this),
suiteDone: _this.onSuiteDone.bind(_this),
jasmineDone: _this.onJasmineDone.bind(_this)
};
// For NodeJS env use the "addReporter" function from the node package.
if (_this.jasmine.addReporter) {
_this.jasmine.addReporter(reporter);
} else {
// For browser env use the "addReporter" function from the jasmine-core.
_this.env.addReporter(reporter);
}
return _this;
}
createClass(JasmineAdapter, [{
key: 'createAssertion',
value: function createAssertion(expectation) {
var stack = expectation.stack !== '' ? expectation.stack : undefined;
return new Assertion(expectation.passed, expectation.actual, expectation.expected, expectation.message, stack);
}
}, {
key: 'saveTestDetails',
value: function saveTestDetails(jasmineSpec) {
var _this2 = this;
var test = this.tests[jasmineSpec.id];
test.errors = [];
test.assertions = [];
jasmineSpec.failedExpectations.forEach(function (expectation) {
test.errors.push(_this2.createAssertion(expectation));
test.assertions.push(_this2.createAssertion(expectation));
});
jasmineSpec.passedExpectations.forEach(function (expectation) {
test.assertions.push(_this2.createAssertion(expectation));
});
if (jasmineSpec.status === 'pending') {
test.status = 'skipped';
} else {
test.status = jasmineSpec.status;
test.runtime = new Date() - this.startTime;
}
}
}, {
key: 'isJasmineGlobalSuite',
value: function isJasmineGlobalSuite(suite) {
return suite.description === 'Jasmine__TopLevel__Suite';
}
/**
* Jasmine provides details about childSuites and tests only in the structure
* returned by "this.env.topSuite()".
*
* This function creates the global suite for the runStart event, as also
* saves the created suites and tests compliant with the CRI standard in an
* object using as key their unique ids provided by Jasmine.
*/
}, {
key: 'createGlobalSuite',
value: function createGlobalSuite(jasmineSuite, fullName) {
var _this3 = this;
var childSuites = [];
var tests = [];
var isGlobalSuite = this.isJasmineGlobalSuite(jasmineSuite);
if (!isGlobalSuite) {
fullName.push(jasmineSuite.description);
}
jasmineSuite.children.forEach(function (child) {
if (child.id.indexOf('suite') === 0) {
childSuites.push(_this3.createGlobalSuite(child, fullName));
} else {
var test = void 0;
var suiteName = !isGlobalSuite ? jasmineSuite.description : undefined;
fullName.push(child.description);
test = new TestEnd(child.description, suiteName, fullName.slice());
fullName.pop();
tests.push(test);
_this3.tests[child.id] = test;
}
});
var name = !isGlobalSuite ? jasmineSuite.description : undefined;
var suite = new SuiteStart(name, fullName.slice(), tests, childSuites);
this.suites[jasmineSuite.id] = suite;
fullName.pop();
return suite;
}
}, {
key: 'onJasmineStarted',
value: function onJasmineStarted() {
this.globalSuite = this.createGlobalSuite(this.env.topSuite(), []);
this.emit('runStart', createSuiteStart(this.globalSuite));
}
}, {
key: 'onSpecStarted',
value: function onSpecStarted(details) {
this.startTime = new Date();
this.emit('testStart', createTestStart(this.tests[details.id]));
}
}, {
key: 'onSpecDone',
value: function onSpecDone(details) {
this.saveTestDetails(details);
this.emit('testEnd', createTestEnd(this.tests[details.id]));
}
}, {
key: 'onSuiteStarted',
value: function onSuiteStarted(details) {
this.emit('suiteStart', createSuiteStart(this.suites[details.id]));
}
}, {
key: 'onSuiteDone',
value: function onSuiteDone(details) {
this.emit('suiteEnd', createSuiteEnd(this.suites[details.id]));
}
}, {
key: 'onJasmineDone',
value: function onJasmineDone() {
this.emit('runEnd', createSuiteEnd(this.globalSuite));
}
}]);
return JasmineAdapter;
}(EventEmitter);
/* global QUnit, mocha, jasmine */
/**
* Auto registers the adapter for the respective testing framework and
* returns the runner for event listening.
*/
function autoRegister() {
var runner;
if (QUnit) {
runner = new QUnitAdapter(QUnit);
} else if (mocha) {
runner = new MochaAdapter(mocha);
} else if (jasmine) {
runner = new JasmineAdapter(jasmine);
} else {
throw new Error('Failed to register js-reporters adapater. Supported ' + 'frameworks are: QUnit, Mocha, Jasmine');
}
return runner;
}
function createSuiteStart(suite) {
return new SuiteStart(suite.name, suite.fullName.slice(), suite.tests.map(createTestStart), suite.childSuites.map(createSuiteStart));
}
function createSuiteEnd(suite) {
return new SuiteEnd(suite.name, suite.fullName.slice(), suite.tests.map(createTestEnd), suite.childSuites.map(createSuiteEnd));
}
function createTestStart(test) {
return new TestStart(test.name, test.suiteName, test.fullName.slice());
}
function createTestEnd(test) {
return new TestEnd(test.name, test.suiteName, test.fullName.slice(), test.status, test.runtime, test.errors.slice(), test.assertions.slice());
}
var QUnitAdapter = function (_EventEmitter) {
inherits(QUnitAdapter, _EventEmitter);
function QUnitAdapter(QUnit) {
classCallCheck(this, QUnitAdapter);
var _this = possibleConstructorReturn(this, (QUnitAdapter.__proto__ || Object.getPrototypeOf(QUnitAdapter)).call(this));
_this.QUnit = QUnit;
_this.tests = {};
_this.delim = ' > ';
QUnit.begin(_this.onBegin.bind(_this));
QUnit.testStart(_this.onTestStart.bind(_this));
QUnit.log(_this.onLog.bind(_this));
QUnit.testDone(_this.onTestDone.bind(_this));
QUnit.done(_this.onDone.bind(_this));
return _this;
}
createClass(QUnitAdapter, [{
key: 'convertModule',
value: function convertModule(qunitModule) {
var _this2 = this;
var fullName = qunitModule.name.split(this.delim).filter(function (value) {
return value !== '';
});
var childSuites = [];
return new SuiteStart(qunitModule.name, fullName.slice(), qunitModule.tests.map(function (qunitTest) {
var indexStart = qunitModule.name.lastIndexOf(_this2.delim);
indexStart = indexStart === -1 ? 0 : indexStart + _this2.delim.length;
fullName.push(qunitTest.name);
var suiteName = qunitModule.name.substring(indexStart);
var test = new TestEnd(qunitTest.name, suiteName, fullName.slice());
_this2.tests[qunitTest.testId] = test;
fullName.pop();
return test;
}), childSuites);
}
}, {
key: 'saveTestDetails',
value: function saveTestDetails(qunitTest) {
var test = this.tests[qunitTest.testId];
test.errors = this.errors;
test.assertions = this.assertions;
if (qunitTest.failed > 0) {
test.status = 'failed';
} else if (qunitTest.skipped) {
test.status = 'skipped';
} else {
test.status = 'passed';
}
// Workaround for QUnit skipped tests runtime which is a Number.
if (test.status !== 'skipped') {
test.runtime = qunitTest.runtime;
} else {
test.runtime = undefined;
}
}
}, {
key: 'createGlobalSuite',
value: function createGlobalSuite() {
var _this3 = this;
var topLevelSuites = [];
var globalSuite;
var modules;
// Access QUnit internals to get all suites and tests, working around
// missing event data.
// Create the global suite first.
if (this.QUnit.config.modules.length > 0 && this.QUnit.config.modules[0].name === '') {
globalSuite = this.convertModule(this.QUnit.config.modules[0]);
globalSuite.name = undefined;
// The suiteName of global tests must be undefined.
globalSuite.tests.forEach(function (test) {
test.suiteName = undefined;
});
modules = this.QUnit.config.modules.slice(1);
} else {
globalSuite = new SuiteStart(undefined, [], [], []);
modules = this.QUnit.config.modules;
}
// Build a list with all suites.
var suites = modules.map(this.convertModule.bind(this));
// Iterate through the whole suites and check if they have composed names,
// like "suiteName1 > suiteName2 > ... > suiteNameN".
//
// If a suite has a composed name, its name will be the last in the sequence
// and its parent name will be the one right before it. Search the parent
// suite after its name and then add the suite with the composed name to the
// childSuites.
//
// If a suite does not have a composed name, add it to the topLevelSuites,
// this means that this suite is the direct child of the global suite.
suites.forEach(function (suite) {
var indexEnd = suite.name.lastIndexOf(_this3.delim);
if (indexEnd !== -1) {
// Find the ' > ' characters that appears before the parent name.
var indexStart = suite.name.substring(0, indexEnd).lastIndexOf(_this3.delim);
// If it is -1, the parent suite name starts at 0, else escape
// this characters ' > '.
indexStart = indexStart === -1 ? 0 : indexStart + _this3.delim.length;
var parentSuiteName = suite.name.substring(indexStart, indexEnd);
// Keep only the name of the suite itself.
suite.name = suite.name.substring(indexEnd + _this3.delim.length);
suites.forEach(function (parentSuite) {
if (parentSuite.name === parentSuiteName) {
parentSuite.childSuites.push(suite);
}
});
} else {
topLevelSuites.push(suite);
}
});
globalSuite.childSuites = topLevelSuites;
return globalSuite;
}
}, {
key: 'createAssertion',
value: function createAssertion(qunitTest) {
return new Assertion(qunitTest.result, qunitTest.actual, qunitTest.expected, qunitTest.message, qunitTest.source || undefined);
}
}, {
key: 'emitData',
value: function emitData(suite) {
var _this4 = this;
suite.tests.forEach(function (test) {
_this4.emit('testStart', createTestStart(test));
_this4.emit('testEnd', createTestEnd(test));
});
suite.childSuites.forEach(function (childSuite) {
_this4.emit('suiteStart', createSuiteStart(childSuite));
_this4.emitData(childSuite);
_this4.emit('suiteEnd', createSuiteEnd(childSuite));
});
}
}, {
key: 'onBegin',
value: function onBegin() {
this.globalSuite = this.createGlobalSuite();
}
}, {
key: 'onTestStart',
value: function onTestStart(details) {
this.errors = [];
this.assertions = [];
}
}, {
key: 'onLog',
value: function onLog(details) {
if (!details.result) {
this.errors.push(this.createAssertion(details));
}
this.assertions.push(this.createAssertion(details));
}
}, {
key: 'onTestDone',
value: function onTestDone(details) {
this.saveTestDetails(details);
}
}, {
key: 'onDone',
value: function onDone() {
this.emit('runStart', createSuiteStart(this.globalSuite));
this.emitData(this.globalSuite);
this.emit('runEnd', createSuiteEnd(this.globalSuite));
}
}]);
return QUnitAdapter;
}(EventEmitter);
var index$2 = createCommonjsModule(function (module) {
'use strict';
var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
module.exports = function (str) {
if (typeof str !== 'string') {
throw new TypeError('Expected a string');
}
return str.replace(matchOperatorsRe, '\\$&');
};
});
var index$3 = interopDefault(index$2);
var require$$4 = Object.freeze({
default: index$3
});
var index$4 = createCommonjsModule(function (module) {
'use strict';
function assembleStyles() {
var styles = {
modifiers: {
reset: [0, 0],
bold: [1, 22], // 21 isn't widely supported and 22 does the same thing
dim: [2, 22],
italic: [3, 23],
underline: [4, 24],
inverse: [7, 27],
hidden: [8, 28],
strikethrough: [9, 29]
},
colors: {
black: [30, 39],
red: [31, 39],
green: [32, 39],
yellow: [33, 39],
blue: [34, 39],
magenta: [35, 39],
cyan: [36, 39],
white: [37, 39],
gray: [90, 39]
},
bgColors: {
bgBlack: [40, 49],
bgRed: [41, 49],
bgGreen: [42, 49],
bgYellow: [43, 49],
bgBlue: [44, 49],
bgMagenta: [45, 49],
bgCyan: [46, 49],
bgWhite: [47, 49]
}
};
// fix humans
styles.colors.grey = styles.colors.gray;
Object.keys(styles).forEach(function (groupName) {
var group = styles[groupName];
Object.keys(group).forEach(function (styleName) {
var style = group[styleName];
styles[styleName] = group[styleName] = {
open: '\x1B[' + style[0] + 'm',
close: '\x1B[' + style[1] + 'm'
};
});
Object.defineProperty(styles, groupName, {
value: group,
enumerable: false
});
});
return styles;
}
Object.defineProperty(module, 'exports', {
enumerable: true,
get: assembleStyles
});
});
var index$5 = interopDefault(index$4);
var require$$3 = Object.freeze({
default: index$5
});
var index$8 = createCommonjsModule(function (module) {
'use strict';
module.exports = function () {
return (/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]/g
);
};
});
var index$9 = interopDefault(index$8);
var require$$0 = Object.freeze({
default: index$9
});
var index$6 = createCommonjsModule(function (module) {
'use strict';
var ansiRegex = interopDefault(require$$0)();
module.exports = function (str) {
return typeof str === 'string' ? str.replace(ansiRegex, '') : str;
};
});
var index$7 = interopDefault(index$6);
var require$$2 = Object.freeze({
default: index$7
});
var index$10 = createCommonjsModule(function (module) {
'use strict';
var ansiRegex = interopDefault(require$$0);
var re = new RegExp(ansiRegex().source); // remove the `g` flag
module.exports = re.test.bind(re);
});
var index$11 = interopDefault(index$10);
var require$$1 = Object.freeze({
default: index$11
});
var index$12 = createCommonjsModule(function (module) {
'use strict';
var argv = process.argv;
var terminator = argv.indexOf('--');
var hasFlag = function hasFlag(flag) {
flag = '--' + flag;
var pos = argv.indexOf(flag);
return pos !== -1 && (terminator !== -1 ? pos < terminator : true);
};
module.exports = function () {
if ('FORCE_COLOR' in process.env) {
return true;
}
if (hasFlag('no-color') || hasFlag('no-colors') || hasFlag('color=false')) {
return false;
}
if (hasFlag('color') || hasFlag('colors') || hasFlag('color=true') || hasFlag('color=always')) {
return true;
}
if (process.stdout && !process.stdout.isTTY) {
return false;
}
if (process.platform === 'win32') {
return true;
}
if ('COLORTERM' in process.env) {
return true;
}
if (process.env.TERM === 'dumb') {
return false;
}
if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) {
return true;
}
return false;
}();
});
var index$13 = interopDefault(index$12);
var require$$0$1 = Object.freeze({
default: index$13
});
var index$1 = createCommonjsModule(function (module) {
'use strict';
var escapeStringRegexp = interopDefault(require$$4);
var ansiStyles = interopDefault(require$$3);
var stripAnsi = interopDefault(require$$2);
var hasAnsi = interopDefault(require$$1);
var supportsColor = interopDefault(require$$0$1);
var defineProps = Object.defineProperties;
var isSimpleWindowsTerm = process.platform === 'win32' && !/^xterm/i.test(process.env.TERM);
function Chalk(options) {
// detect mode if not set manually
this.enabled = !options || options.enabled === undefined ? supportsColor : options.enabled;
}
// use bright blue on Windows as the normal blue color is illegible
if (isSimpleWindowsTerm) {
ansiStyles.blue.open = '\x1B[94m';
}
var styles = function () {
var ret = {};
Object.keys(ansiStyles).forEach(function (key) {
ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
ret[key] = {
get: function get() {
return build.call(this, this._styles.concat(key));
}
};
});
return ret;
}();
var proto = defineProps(function chalk() {}, styles);
function build(_styles) {
var builder = function builder() {
return applyStyle.apply(builder, arguments);
};
builder._styles = _styles;
builder.enabled = this.enabled;
// __proto__ is used because we must return a function, but there is
// no way to create a function with a different prototype.
/* eslint-disable no-proto */
builder.__proto__ = proto;
return builder;
}
function applyStyle() {
// support varags, but simply cast to string in case there's only one arg
var args = arguments;
var argsLen = args.length;
var str = argsLen !== 0 && String(arguments[0]);
if (argsLen > 1) {
// don't slice `arguments`, it prevents v8 optimizations
for (var a = 1; a < argsLen; a++) {
str += ' ' + args[a];
}
}
if (!this.enabled || !str) {
return str;
}
var nestedStyles = this._styles;
var i = nestedStyles.length;
// Turns out that on Windows dimmed gray text becomes invisible in cmd.exe,
// see https://github.com/chalk/chalk/issues/58
// If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop.
var originalDim = ansiStyles.dim.open;
if (isSimpleWindowsTerm && (nestedStyles.indexOf('gray') !== -1 || nestedStyles.indexOf('grey') !== -1)) {
ansiStyles.dim.open = '';
}
while (i--) {
var code = ansiStyles[nestedStyles[i]];
// Replace any instances already present with a re-opening code
// otherwise only the part of the string until said closing code
// will be colored, and the rest will simply be 'plain'.
str = code.open + str.replace(code.closeRe, code.open) + code.close;
}
// Reset the original 'dim' if we changed it to work around the Windows dimmed gray issue.
ansiStyles.dim.open = originalDim;
return str;
}
function init() {
var ret = {};
Object.keys(styles).forEach(function (name) {
ret[name] = {
get: function get() {
return build.call(this, [name]);
}
};
});
return ret;
}
defineProps(Chalk.prototype, init());
module.exports = new Chalk();
module.exports.styles = ansiStyles;
module.exports.hasColor = hasAnsi;
module.exports.stripColor = stripAnsi;
module.exports.supportsColor = supportsColor;
});
var chalk = interopDefault(index$1);
var TapReporter = function () {
function TapReporter(runner) {
classCallCheck(this, TapReporter);
this.testCount = 0;
runner.on('runStart', this.onRunStart.bind(this));
runner.on('testEnd', this.onTestEnd.bind(this));
runner.on('runEnd', this.onRunEnd.bind(this));
}
createClass(TapReporter, [{
key: 'onRunStart',
value: function onRunStart(globalSuite) {
console.log('TAP version 13');
}
}, {
key: 'onTestEnd',
value: function onTestEnd(test) {
var _this = this;
this.testCount = this.testCount + 1;
if (test.status === 'passed') {
console.log('ok ' + this.testCount + ' ' + test.fullName.join(' > '));
} else if (test.status === 'skipped') {
console.log(chalk.yellow('ok ' + this.testCount + ' # SKIP ' + test.fullName.join(' > ')));
} else if (test.status === 'todo') {
console.log(chalk.cyan('not ok ' + this.testCount + ' # TODO ' + test.fullName.join(' > ')));
test.errors.forEach(function (error) {
return _this.logError(error, 'todo');
});
} else {
console.log(chalk.red('not ok ' + this.testCount + ' ' + test.fullName.join(' > ')));
test.errors.forEach(function (error) {
return _this.logError(error);
});
}
}
}, {
key: 'onRunEnd',
value: function onRunEnd(globalSuite) {
console.log('1..' + globalSuite.testCounts.total);
console.log('# pass ' + globalSuite.testCounts.passed);
console.log(chalk.yellow('# skip ' + globalSuite.testCounts.skipped));
console.log(chalk.cyan('# todo ' + globalSuite.testCounts.todo));
console.log(chalk.red('# fail ' + globalSuite.testCounts.failed));
}
}, {
key: 'logError',
value: function logError(error, severity) {
console.log(' ---');
console.log(' message: "' + (error.message || 'failed') + '"');
console.log(' severity: ' + (severity || 'failed'));
if (error.hasOwnProperty('actual')) {
var actualStr = error.actual !== undefined ? JSON.stringify(error.actual, null, 2) : 'undefined';
console.log(' actual: ' + actualStr);
}
if (error.hasOwnProperty('expected')) {
var expectedStr = error.expected !== undefined ? JSON.stringify(error.expected, null, 2) : 'undefined';
console.log(' expected: ' + expectedStr);
}
if (error.stack) {
console.log(' stack: ' + error.stack);
}
console.log(' ...');
}
}], [{
key: 'init',
value: function init(runner) {
return new TapReporter(runner);
}
}]);
return TapReporter;
}();
// TODO: finish grouping once suiteStart is implemented
var hasGrouping = 'group' in console && 'groupEnd' in console;
var ConsoleReporter = function () {
function ConsoleReporter(runner) {
classCallCheck(this, ConsoleReporter);
runner.on('runStart', this.onRunStart);
runner.on('suiteStart', this.onSuiteStart);
runner.on('testStart', this.onTestStart);
runner.on('testEnd', this.onTestEnd);
runner.on('suiteEnd', this.onSuiteEnd);
runner.on('runEnd', this.onRunEnd);
}
createClass(ConsoleReporter, [{
key: 'onRunStart',
value: function onRunStart(suite) {
console.log('runStart', suite);
}
}, {
key: 'onSuiteStart',
value: function onSuiteStart(suite) {
if (hasGrouping) {
console.group(suite.name);
}
console.log('suiteStart', suite);
}
}, {
key: 'onTestStart',
value: function onTestStart(test) {
console.log('testStart', test);
}
}, {
key: 'onTestEnd',
value: function onTestEnd(test) {
console.log('testEnd', test);
}
}, {
key: 'onSuiteEnd',
value: function onSuiteEnd(suite) {
console.log('suiteEnd', suite);
if (hasGrouping) {
console.groupEnd();
}
}
}, {
key: 'onRunEnd',
value: function onRunEnd(globalSuite) {
console.log('runEnd', globalSuite);
}
}], [{
key: 'init',
value: function init(runner) {
return new ConsoleReporter(runner);
}
}]);
return ConsoleReporter;
}();
var index = {
QUnitAdapter: QUnitAdapter,
JasmineAdapter: JasmineAdapter,
MochaAdapter: MochaAdapter,
TapReporter: TapReporter,
ConsoleReporter: ConsoleReporter,
Assertion: Assertion,
TestStart: TestStart,
TestEnd: TestEnd,
SuiteStart: SuiteStart,
SuiteEnd: SuiteEnd,
createSuiteStart: createSuiteStart,
createTestStart: createTestStart,
createTestEnd: createTestEnd,
createSuiteEnd: createSuiteEnd,
autoRegister: autoRegister
};
return index;
})));