Socket
Socket
Sign inDemoInstall

js-reporters

Package Overview
Dependencies
0
Maintainers
2
Versions
9
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.1 to 1.1.0

2019

dist/js-reporters.js
/**
* JsReporters 1.0.1
* JsReporters 1.1.0
* https://github.com/js-reporters

@@ -9,1205 +9,1178 @@ *

*
* Date: Fri Jul 15 2016
* Date: Wed Aug 10 2016
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.JsReporters = 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 __commonjs(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; }
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 babelHelpers = {};
babelHelpers.typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
};
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
};
babelHelpers.classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
babelHelpers.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);
}
}
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;
};
}();
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
babelHelpers.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);
}
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;
};
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;
};
babelHelpers.possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
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;
};
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
babelHelpers.slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
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.
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
function EventEmitter() {
this._events = this._events || {};
this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
return _arr;
}
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
// 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;
babelHelpers;
// 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;
};
var events = __commonjs(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.
EventEmitter.prototype.emit = function (type) {
var er, handler, len, args, i, listeners;
function EventEmitter() {
this._events = this._events || {};
this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;
if (!this._events) this._events = {};
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
// 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;
}
}
}
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;
handler = this._events[type];
// 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;
if (isUndefined(handler)) return false;
// 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;
};
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);
}
}
EventEmitter.prototype.emit = function (type) {
var er, handler, len, args, i, listeners;
return true;
};
if (!this._events) this._events = {};
EventEmitter.prototype.addListener = function (type, listener) {
var m;
// 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
}
throw TypeError('Uncaught, unspecified "error" event.');
}
}
if (!isFunction(listener)) throw TypeError('listener must be a function');
handler = this._events[type];
if (!this._events) this._events = {};
if (isUndefined(handler)) return false;
// 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 (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);
}
}
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];
return true;
};
// Check for listener leak
if (isObject(this._events[type]) && !this._events[type].warned) {
if (!isUndefined(this._maxListeners)) {
m = this._maxListeners;
} else {
m = EventEmitter.defaultMaxListeners;
}
EventEmitter.prototype.addListener = function (type, listener) {
var m;
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();
}
}
}
if (!isFunction(listener)) throw TypeError('listener must be a function');
return this;
};
if (!this._events) this._events = {};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
// 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);
EventEmitter.prototype.once = function (type, listener) {
if (!isFunction(listener)) throw TypeError('listener must be a function');
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];
var fired = false;
// Check for listener leak
if (isObject(this._events[type]) && !this._events[type].warned) {
if (!isUndefined(this._maxListeners)) {
m = this._maxListeners;
} else {
m = EventEmitter.defaultMaxListeners;
}
function g() {
this.removeListener(type, g);
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();
}
}
}
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
}
return this;
};
g.listener = listener;
this.on(type, g);
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
return this;
};
EventEmitter.prototype.once = function (type, listener) {
if (!isFunction(listener)) throw TypeError('listener must be a function');
// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener = function (type, listener) {
var list, position, length, i;
var fired = false;
if (!isFunction(listener)) throw TypeError('listener must be a function');
function g() {
this.removeListener(type, g);
if (!this._events || !this._events[type]) return this;
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
}
list = this._events[type];
length = list.length;
position = -1;
g.listener = listener;
this.on(type, g);
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;
}
}
return this;
};
if (position < 0) return this;
// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener = function (type, listener) {
var list, position, length, i;
if (list.length === 1) {
list.length = 0;
delete this._events[type];
} else {
list.splice(position, 1);
}
if (!isFunction(listener)) throw TypeError('listener must be a function');
if (this._events.removeListener) this.emit('removeListener', type, listener);
}
if (!this._events || !this._events[type]) return this;
return this;
};
list = this._events[type];
length = list.length;
position = -1;
EventEmitter.prototype.removeAllListeners = function (type) {
var key, listeners;
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 (!this._events) return this;
if (position < 0) 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;
}
if (list.length === 1) {
list.length = 0;
delete this._events[type];
} else {
list.splice(position, 1);
}
// 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;
}
if (this._events.removeListener) this.emit('removeListener', type, listener);
}
listeners = this._events[type];
return this;
};
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];
EventEmitter.prototype.removeAllListeners = function (type) {
var key, listeners;
return this;
};
if (!this._events) 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;
};
// 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;
}
EventEmitter.prototype.listenerCount = function (type) {
if (this._events) {
var evlistener = this._events[type];
// 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;
}
if (isFunction(evlistener)) return 1;else if (evlistener) return evlistener.length;
}
return 0;
};
listeners = this._events[type];
EventEmitter.listenerCount = function (emitter, type) {
return emitter.listenerCount(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];
function isFunction(arg) {
return typeof arg === 'function';
}
return this;
};
function isNumber(arg) {
return typeof arg === 'number';
}
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;
};
function isObject(arg) {
return (typeof arg === 'undefined' ? 'undefined' : _typeof(arg)) === 'object' && arg !== null;
}
EventEmitter.prototype.listenerCount = function (type) {
if (this._events) {
var evlistener = this._events[type];
function isUndefined(arg) {
return arg === void 0;
}
});
if (isFunction(evlistener)) return 1;else if (evlistener) return evlistener.length;
}
return 0;
};
var EventEmitter = interopDefault(events);
EventEmitter.listenerCount = function (emitter, type) {
return emitter.listenerCount(type);
};
function getAllTests(suite) {
var childSuiteTests = suite.childSuites.map(function (childSuite) {
return getAllTests(childSuite);
}).reduce(function (allTests, a) {
return allTests.concat(a);
}, []);
function isFunction(arg) {
return typeof arg === 'function';
}
return suite.tests.concat(childSuiteTests);
}
function isNumber(arg) {
return typeof arg === 'number';
}
function getRuntime(suite) {
if (suite.status === 'skipped' || suite.status === undefined) {
return undefined;
}
function isObject(arg) {
return (typeof arg === 'undefined' ? 'undefined' : babelHelpers.typeof(arg)) === 'object' && arg !== null;
}
return getAllTests(suite).map(function (test) {
return test.status === 'skipped' ? 0 : test.runtime;
}).reduce(function (sum, testRuntime) {
return sum + testRuntime;
}, 0);
}
function isUndefined(arg) {
return arg === void 0;
}
});
function getStatus(suite) {
var passed = 0;
var failed = 0;
var skipped = 0;
var tests = getAllTests(suite);
var EventEmitter = events && (typeof events === 'undefined' ? 'undefined' : babelHelpers.typeof(events)) === 'object' && 'default' in events ? events['default'] : events;
for (var i = 0; i < tests.length; i++) {
var test = tests[i];
var Test = function Test(testName, suiteName, status, runtime, errors) {
babelHelpers.classCallCheck(this, Test);
// 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 {
failed++;
}
}
this.testName = testName;
this.suiteName = suiteName;
this.status = status;
this.runtime = runtime;
this.errors = errors;
};
if (failed > 0) {
return 'failed';
} else if (skipped > 0 && passed === 0) {
return 'skipped';
} else {
return 'passed';
}
}
var Suite = function () {
function getTestCounts(suite) {
var tests = getAllTests(suite);
/**
*
* @param name
* @param childSuites
* @param tests: array containing tests belonging to the suite but not to a child suite
*/
// If the suite does not have a status, it means that its tests haven't
// finished to run, so we know only the total.
if (!suite.status) {
return {
passed: undefined,
failed: undefined,
skipped: undefined,
total: tests.length
};
}
function Suite(name, childSuites, tests) {
babelHelpers.classCallCheck(this, 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,
total: tests.length
};
}
this.name = name;
this.childSuites = childSuites;
this.tests = tests;
}
var Assertion =
/**
* @param {Boolean} passed
* @param {*} actual
* @param {*} expected
* @param {String} message
* @param {String|undefined} stack
*/
function Assertion(passed, actual, expected, message, stack) {
classCallCheck(this, Assertion);
babelHelpers.createClass(Suite, [{
key: 'getAllTests',
value: function getAllTests() {
var childSuiteTests = this.childSuites.map(function (suite) {
return suite.getAllTests();
}).reduce(function (allTests, a) {
return allTests.concat(a);
}, []);
this.passed = passed;
this.actual = actual;
this.expected = expected;
this.message = message;
this.stack = stack;
};
return this.tests.concat(childSuiteTests);
}
}, {
key: 'runtime',
get: function get() {
var status = this.status;
var Test =
/**
* @param {String} name
* @param {String} suiteName
* @param {String[]} fullName
* @param {String} status
* @param {Number} runtime
* @param {Assertion[]} errors
* @param {Assertion[]} assertions
*/
function Test(name, suiteName, fullName, status, runtime, errors, assertions) {
classCallCheck(this, Test);
if (status === 'skipped' || status === undefined) {
return undefined;
}
this.name = name;
this.suiteName = suiteName;
this.fullName = fullName;
this.status = status;
this.runtime = runtime;
this.errors = errors;
this.assertions = assertions;
};
var runtime = this.getAllTests().map(function (test) {
return test.status === 'skipped' ? 0 : test.runtime;
}).reduce(function (sum, testRuntime) {
return sum + testRuntime;
}, 0);
var Suite =
/**
* @param {String} name
* @param {String[]} fullName
* @param {Suite[]} childSuites
* @param {Test[]} tests
*/
function Suite(name, fullName, childSuites, tests) {
classCallCheck(this, Suite);
return runtime;
}
}, {
key: 'status',
get: function get() {
var passed = 0;
var failed = 0;
var skipped = 0;
var tests = this.getAllTests();
this.name = name;
this.fullName = fullName;
this.childSuites = childSuites;
this.tests = tests;
/**
* @type {String}
*/
this.status = getStatus(this);
/**
* @param {Object} testCounts
* @param {Number} testCounts.passed
* @param {Number} testCounts.failed
* @param {Number} testCounts.skipped
* @param {Number} testCounts.total
*/
this.testCounts = getTestCounts(this);
/**
* @type {Number}
*/
this.runtime = getRuntime(this);
};
for (var i = 0; i < tests.length; i++) {
var test = tests[i];
var QUnitAdapter = function (_EventEmitter) {
inherits(QUnitAdapter, _EventEmitter);
// 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 {
failed++;
}
}
function QUnitAdapter(QUnit) {
classCallCheck(this, QUnitAdapter);
if (failed > 0) {
return 'failed';
} else if (skipped > 0 && passed === 0) {
return 'skipped';
} else {
return 'passed';
}
}
}]);
return Suite;
}();
var _this = possibleConstructorReturn(this, Object.getPrototypeOf(QUnitAdapter).call(this));
Object.defineProperties(Suite.prototype, {
toJSON: {
value: function value() {
var ret = {};
for (var x in this) {
ret[x] = this[x];
}
return ret;
}
},
runtime: {
enumerable: true
},
status: {
enumerable: true
}
});
_this.QUnit = QUnit;
_this.tests = {};
_this.delim = ' > ';
var QUnitAdapter = function (_EventEmitter) {
babelHelpers.inherits(QUnitAdapter, _EventEmitter);
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;
}
function QUnitAdapter(QUnit) {
babelHelpers.classCallCheck(this, QUnitAdapter);
createClass(QUnitAdapter, [{
key: 'convertModule',
value: function convertModule(qunitModule) {
var _this2 = this;
var _this = babelHelpers.possibleConstructorReturn(this, Object.getPrototypeOf(QUnitAdapter).call(this));
var fullName = qunitModule.name.split(this.delim).filter(function (value) {
return value !== '';
});
var childSuites = [];
_this.QUnit = QUnit;
_this.tests = {};
return new Suite(qunitModule.name, fullName.slice(), childSuites, qunitModule.tests.map(function (qunitTest) {
var indexStart = qunitModule.name.lastIndexOf(_this2.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;
}
indexStart = indexStart === -1 ? 0 : indexStart + _this2.delim.length;
fullName.push(qunitTest.name);
babelHelpers.createClass(QUnitAdapter, [{
key: 'convertModule',
value: function convertModule(qunitModule) {
var _this2 = this;
var suiteName = qunitModule.name.substring(indexStart);
var test = new Test(qunitTest.name, suiteName, fullName.slice());
return new Suite(qunitModule.name, [], qunitModule.tests.map(function (qunitTest) {
var test = new Test(qunitTest.name, qunitModule.name.replace(/> /g, ''));
_this2.tests[qunitTest.testId] = test;
fullName.pop();
_this2.tests[qunitTest.testId] = test;
return test;
}));
}
}, {
key: 'saveTestDetails',
value: function saveTestDetails(qunitTest) {
var test = this.tests[qunitTest.testId];
return test;
}));
}
}, {
key: 'saveTestDetails',
value: function saveTestDetails(qunitTest) {
var test = this.tests[qunitTest.testId];
test.errors = this.errors;
test.assertions = this.assertions;
test.errors = this.errors;
if (qunitTest.failed > 0) {
test.status = 'failed';
} else if (qunitTest.skipped) {
test.status = 'skipped';
} else {
test.status = 'passed';
}
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;
// 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 topLevelSuites = [];
var globalSuite;
var modules;
var topLevelSuites = [];
var globalSuite;
var modules;
// Access QUnit internals to get all suites and tests, working around
// missing event data.
// 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;
// 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;
});
// 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 Suite(undefined, [], []);
modules = this.QUnit.config.modules;
}
modules = this.QUnit.config.modules.slice(1);
} else {
globalSuite = new Suite(undefined, [], [], []);
modules = this.QUnit.config.modules;
}
// Build a list with all suites.
var suites = modules.map(this.convertModule.bind(this));
// 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(' > ');
// 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(' > ');
// If it is -1, the parent suite name starts at 0, else escape
// this characters ' > '.
indexStart = indexStart === -1 ? 0 : indexStart + 3;
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);
var parentSuiteName = suite.name.substring(indexStart, indexEnd);
// Keep only the name of the suite itself.
suite.name = suite.name.substring(indexEnd + 3);
// 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);
}
});
suites.forEach(function (parentSuite) {
if (parentSuite.name === parentSuiteName) {
parentSuite.childSuites.push(suite);
}
});
} else {
topLevelSuites.push(suite);
}
});
globalSuite.childSuites = topLevelSuites;
globalSuite.childSuites = topLevelSuites;
return globalSuite;
}
}, {
key: 'createSuiteStart',
value: function createSuiteStart(suite) {
return new Suite(suite.name, suite.childSuites.map(this.createSuiteStart.bind(this)), suite.tests.map(this.createTestStart.bind(this)));
}
}, {
key: 'createSuiteEnd',
value: function createSuiteEnd(suite) {
return new Suite(suite.name, suite.childSuites.map(this.createSuiteEnd.bind(this)), suite.tests.map(this.createTestEnd.bind(this)));
}
}, {
key: 'createTestStart',
value: function createTestStart(test) {
return new Test(test.testName, test.suiteName);
}
}, {
key: 'createTestEnd',
value: function createTestEnd(test) {
return new Test(test.testName, test.suiteName, test.status, test.runtime, test.errors);
}
}, {
key: 'emitData',
value: function emitData(suite) {
var _this3 = this;
return globalSuite;
}
}, {
key: 'createSuiteStart',
value: function createSuiteStart(suite) {
return new Suite(suite.name, suite.fullName, suite.childSuites.map(this.createSuiteStart.bind(this)), suite.tests.map(this.createTestStart.bind(this)));
}
}, {
key: 'createSuiteEnd',
value: function createSuiteEnd(suite) {
return new Suite(suite.name, suite.fullName, suite.childSuites.map(this.createSuiteEnd.bind(this)), suite.tests.map(this.createTestEnd.bind(this)));
}
}, {
key: 'createTestStart',
value: function createTestStart(test) {
return new Test(test.name, test.suiteName, test.fullName);
}
}, {
key: 'createTestEnd',
value: function createTestEnd(test) {
return new Test(test.name, test.suiteName, test.fullName, test.status, test.runtime, test.errors, test.assertions);
}
}, {
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) {
_this3.emit('testStart', _this3.createTestStart(test));
_this3.emit('testEnd', _this3.createTestEnd(test));
});
suite.tests.forEach(function (test) {
_this4.emit('testStart', _this4.createTestStart(test));
_this4.emit('testEnd', _this4.createTestEnd(test));
});
suite.childSuites.forEach(function (childSuite) {
_this3.emit('suiteStart', _this3.createSuiteStart(childSuite));
_this3.emitData(childSuite);
_this3.emit('suiteEnd', _this3.createSuiteEnd(childSuite));
});
}
}, {
key: 'onBegin',
value: function onBegin() {
this.globalSuite = this.createGlobalSuite();
}
}, {
key: 'onTestStart',
value: function onTestStart(details) {
this.errors = [];
}
}, {
key: 'onLog',
value: function onLog(details) {
if (!details.result) {
this.errors.push(details);
}
}
}, {
key: 'onTestDone',
value: function onTestDone(details) {
this.saveTestDetails(details);
}
}, {
key: 'onDone',
value: function onDone() {
this.emit('runStart', this.createSuiteStart(this.globalSuite));
this.emitData(this.globalSuite);
this.emit('runEnd', this.createSuiteEnd(this.globalSuite));
}
}]);
return QUnitAdapter;
}(EventEmitter);
suite.childSuites.forEach(function (childSuite) {
_this4.emit('suiteStart', _this4.createSuiteStart(childSuite));
_this4.emitData(childSuite);
_this4.emit('suiteEnd', _this4.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));
}
/**
* Limitations:
* - Errors in afterAll are ignored.
*/
this.assertions.push(this.createAssertion(details));
}
}, {
key: 'onTestDone',
value: function onTestDone(details) {
this.saveTestDetails(details);
}
}, {
key: 'onDone',
value: function onDone() {
this.emit('runStart', this.createSuiteStart(this.globalSuite));
this.emitData(this.globalSuite);
this.emit('runEnd', this.createSuiteEnd(this.globalSuite));
}
}]);
return QUnitAdapter;
}(EventEmitter);
var JasmineAdapter = function (_EventEmitter) {
babelHelpers.inherits(JasmineAdapter, _EventEmitter);
/**
* Limitations:
* - Errors in afterAll are ignored.
*/
function JasmineAdapter(jasmine) {
babelHelpers.classCallCheck(this, JasmineAdapter);
var JasmineAdapter = function (_EventEmitter) {
inherits(JasmineAdapter, _EventEmitter);
var _this = babelHelpers.possibleConstructorReturn(this, Object.getPrototypeOf(JasmineAdapter).call(this));
function JasmineAdapter(jasmine) {
classCallCheck(this, JasmineAdapter);
_this.jasmine = jasmine;
jasmine.addReporter({
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)
});
var _this = possibleConstructorReturn(this, Object.getPrototypeOf(JasmineAdapter).call(this));
_this.suites = {};
_this.tests = {};
return _this;
}
_this.jasmine = jasmine;
_this.suites = {};
_this.tests = {};
babelHelpers.createClass(JasmineAdapter, [{
key: 'createSuiteStart',
value: function createSuiteStart(suite) {
return new Suite(suite.name, suite.childSuites.map(this.createSuiteStart.bind(this)), suite.tests.map(this.createTestStart.bind(this)));
}
}, {
key: 'createSuiteEnd',
value: function createSuiteEnd(suite) {
return new Suite(suite.name, suite.childSuites.map(this.createSuiteEnd.bind(this)), suite.tests.map(this.createTestEnd.bind(this)));
}
}, {
key: 'createTestStart',
value: function createTestStart(test) {
return new Test(test.testName, test.suiteName);
}
}, {
key: 'createTestEnd',
value: function createTestEnd(test) {
return new Test(test.testName, test.suiteName, test.status, test.runtime, test.errors);
}
}, {
key: 'saveTestDetails',
value: function saveTestDetails(jasmineSpec) {
var test = this.tests[jasmineSpec.id];
jasmine.addReporter({
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)
});
return _this;
}
test.errors = jasmineSpec.failedExpectations;
createClass(JasmineAdapter, [{
key: 'createSuiteStart',
value: function createSuiteStart(suite) {
return new Suite(suite.name, suite.fullName, suite.childSuites.map(this.createSuiteStart.bind(this)), suite.tests.map(this.createTestStart.bind(this)));
}
}, {
key: 'createSuiteEnd',
value: function createSuiteEnd(suite) {
return new Suite(suite.name, suite.fullName, suite.childSuites.map(this.createSuiteEnd.bind(this)), suite.tests.map(this.createTestEnd.bind(this)));
}
}, {
key: 'createTestStart',
value: function createTestStart(test) {
return new Test(test.name, test.suiteName, test.fullName);
}
}, {
key: 'createTestEnd',
value: function createTestEnd(test) {
return new Test(test.name, test.suiteName, test.fullName, test.status, test.runtime, test.errors, test.assertions);
}
}, {
key: 'createAssertion',
value: function createAssertion(expectation) {
var stack = expectation.stack !== '' ? expectation.stack : undefined;
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';
}
return new Assertion(expectation.passed, expectation.actual, expectation.expected, expectation.message, stack);
}
}, {
key: 'saveTestDetails',
value: function saveTestDetails(jasmineSpec) {
var _this2 = this;
/**
* Jasmine provides details about childSuites and tests only in the structure
* returned by "this.jasmine.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.
*/
var test = this.tests[jasmineSpec.id];
}, {
key: 'createGlobalSuite',
value: function createGlobalSuite(jasmineSuite) {
var _this2 = this;
test.errors = [];
test.assertions = [];
var childSuites = [];
var tests = [];
jasmineSpec.failedExpectations.forEach(function (expectation) {
test.errors.push(_this2.createAssertion(expectation));
test.assertions.push(_this2.createAssertion(expectation));
});
jasmineSuite.children.forEach(function (child) {
if (child.id.indexOf('suite') === 0) {
childSuites.push(_this2.createGlobalSuite(child));
} else {
var suiteName = void 0;
var test = void 0;
jasmineSpec.passedExpectations.forEach(function (expectation) {
test.assertions.push(_this2.createAssertion(expectation));
});
// Jasmine full description is of form "suite1 suite2 ... suiteN test",
// for the "suiteName" property we need to remove test name.
if (!_this2.isJasmineGlobalSuite(jasmineSuite)) {
suiteName = child.result.fullName.substring(0, child.result.fullName.indexOf(child.description) - 1);
}
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';
}
test = new Test(child.description, suiteName);
/**
* Jasmine provides details about childSuites and tests only in the structure
* returned by "this.jasmine.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.
*/
tests.push(test);
_this2.tests[child.id] = test;
}
});
}, {
key: 'createGlobalSuite',
value: function createGlobalSuite(jasmineSuite, fullName) {
var _this3 = this;
var name = this.isJasmineGlobalSuite(jasmineSuite) ? undefined : jasmineSuite.description;
var suite = new Suite(name, childSuites, tests);
var childSuites = [];
var tests = [];
var isGlobalSuite = this.isJasmineGlobalSuite(jasmineSuite);
this.suites[jasmineSuite.id] = suite;
if (!isGlobalSuite) {
fullName.push(jasmineSuite.description);
}
return suite;
}
}, {
key: 'onJasmineStarted',
value: function onJasmineStarted() {
this.globalSuite = this.createGlobalSuite(this.jasmine.topSuite());
this.emit('runStart', this.createSuiteStart(this.globalSuite));
}
}, {
key: 'onSpecStarted',
value: function onSpecStarted(details) {
this.startTime = new Date();
this.emit('testStart', this.createTestStart(this.tests[details.id]));
}
}, {
key: 'onSpecDone',
value: function onSpecDone(details) {
this.saveTestDetails(details);
this.emit('testEnd', this.createTestEnd(this.tests[details.id]));
}
}, {
key: 'onSuiteStarted',
value: function onSuiteStarted(details) {
this.emit('suiteStart', this.createSuiteStart(this.suites[details.id]));
}
}, {
key: 'onSuiteDone',
value: function onSuiteDone(details) {
this.emit('suiteEnd', this.createSuiteEnd(this.suites[details.id]));
}
}, {
key: 'onJasmineDone',
value: function onJasmineDone() {
this.emit('runEnd', this.createSuiteEnd(this.globalSuite));
}
}]);
return JasmineAdapter;
}(EventEmitter);
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;
var MochaAdapter = function (_EventEmitter) {
babelHelpers.inherits(MochaAdapter, _EventEmitter);
fullName.push(child.description);
function MochaAdapter(mocha) {
babelHelpers.classCallCheck(this, MochaAdapter);
test = new Test(child.description, suiteName, fullName.slice());
var _this = babelHelpers.possibleConstructorReturn(this, Object.getPrototypeOf(MochaAdapter).call(this));
fullName.pop();
_this.mocha = mocha;
_this.origReporter = mocha._reporter;
tests.push(test);
_this3.tests[child.id] = test;
}
});
mocha.reporter(function (runner) {
_this.runner = runner;
var name = !isGlobalSuite ? jasmineSuite.description : undefined;
var suite = new Suite(name, fullName.slice(), childSuites, tests);
// eslint-disable-next-line no-unused-vars
var origReporterInstance = new (_this.origReporter.bind(_this.mocha, _this.runner))();
this.suites[jasmineSuite.id] = suite;
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;
}
fullName.pop();
babelHelpers.createClass(MochaAdapter, [{
key: 'convertSuite',
value: function convertSuite(mochaSuite) {
return new Suite(mochaSuite.title, mochaSuite.suites.map(this.convertSuite.bind(this)), mochaSuite.tests.map(this.convertTest.bind(this)));
}
}, {
key: 'convertTest',
value: function convertTest(mochaTest) {
var suiteName;
return suite;
}
}, {
key: 'onJasmineStarted',
value: function onJasmineStarted() {
this.globalSuite = this.createGlobalSuite(this.jasmine.topSuite(), []);
this.emit('runStart', this.createSuiteStart(this.globalSuite));
}
}, {
key: 'onSpecStarted',
value: function onSpecStarted(details) {
this.startTime = new Date();
this.emit('testStart', this.createTestStart(this.tests[details.id]));
}
}, {
key: 'onSpecDone',
value: function onSpecDone(details) {
this.saveTestDetails(details);
this.emit('testEnd', this.createTestEnd(this.tests[details.id]));
}
}, {
key: 'onSuiteStarted',
value: function onSuiteStarted(details) {
this.emit('suiteStart', this.createSuiteStart(this.suites[details.id]));
}
}, {
key: 'onSuiteDone',
value: function onSuiteDone(details) {
this.emit('suiteEnd', this.createSuiteEnd(this.suites[details.id]));
}
}, {
key: 'onJasmineDone',
value: function onJasmineDone() {
this.emit('runEnd', this.createSuiteEnd(this.globalSuite));
}
}]);
return JasmineAdapter;
}(EventEmitter);
if (!mochaTest.parent.root) {
suiteName = this.buildSuiteName(mochaTest.parent);
}
var MochaAdapter = function (_EventEmitter) {
inherits(MochaAdapter, _EventEmitter);
// 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;
function MochaAdapter(mocha) {
classCallCheck(this, MochaAdapter);
// Test end.
return new Test(mochaTest.title, suiteName, status, mochaTest.duration, mochaTest.errors);
}
var _this = possibleConstructorReturn(this, Object.getPrototypeOf(MochaAdapter).call(this));
// Test start.
return new Test(mochaTest.title, suiteName);
}
_this.mocha = mocha;
_this.origReporter = mocha._reporter;
/**
* Builds a concatenated name from nested suites.
*/
mocha.reporter(function (runner) {
_this.runner = runner;
}, {
key: 'buildSuiteName',
value: function buildSuiteName(mochaSuite) {
var suiteName = mochaSuite.title;
var parent = mochaSuite.parent;
// eslint-disable-next-line no-unused-vars
var origReporterInstance = new (_this.origReporter.bind(_this.mocha, _this.runner))();
while (!parent.root) {
suiteName = parent.title + ' ' + suiteName;
parent = parent.parent;
}
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;
}
return suiteName;
}
}, {
key: 'onStart',
value: function onStart() {
var globalSuiteStart = this.convertSuite(this.runner.suite);
globalSuiteStart.name = undefined;
createClass(MochaAdapter, [{
key: 'convertSuite',
value: function convertSuite(mochaSuite) {
return new Suite(mochaSuite.title, this.buildSuiteFullName(mochaSuite), mochaSuite.suites.map(this.convertSuite.bind(this)), mochaSuite.tests.map(this.convertTest.bind(this)));
}
}, {
key: 'convertTest',
value: function convertTest(mochaTest) {
var suiteName;
var fullName;
this.emit('runStart', globalSuiteStart);
}
}, {
key: 'onSuite',
value: function onSuite(mochaSuite) {
if (!mochaSuite.root) {
this.emit('suiteStart', this.convertSuite(mochaSuite));
}
}
}, {
key: 'onTest',
value: function onTest(mochaTest) {
this.errors = [];
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];
}
this.emit('testStart', this.convertTest(mochaTest));
}
// If the test has the errors attached a "test end" must be emitted, else
// a "test start".
if (mochaTest.errors !== undefined) {
var status;
/**
* Emits the start of pending tests, because Mocha does not emit skipped tests
* on its "test" event.
*/
var _ret = function () {
status = mochaTest.state === undefined ? 'skipped' : mochaTest.state;
}, {
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;
var errors = [];
this.emit('testEnd', this.convertTest(mochaTest));
}
}, {
key: 'onSuiteEnd',
value: function onSuiteEnd(mochaSuite) {
if (!mochaSuite.root) {
this.emit('suiteEnd', this.convertSuite(mochaSuite));
}
}
}, {
key: 'onEnd',
value: function onEnd() {
var globalSuiteEnd = this.convertSuite(this.runner.suite);
globalSuiteEnd.name = undefined;
mochaTest.errors.forEach(function (error) {
errors.push(new Assertion(false, error.actual, error.expected, error.message || error.toString(), error.stack));
});
this.emit('runEnd', globalSuiteEnd);
}
}]);
return MochaAdapter;
}(EventEmitter);
// Test end, for the assertions property pass an empty array.
return {
v: new Test(mochaTest.title, suiteName, fullName, status, mochaTest.duration, errors, errors)
};
}();
var TapReporter = function () {
function TapReporter(runner) {
babelHelpers.classCallCheck(this, TapReporter);
if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
}
this.testCount = 0;
// Test start.
return new Test(mochaTest.title, suiteName, fullName);
}
runner.on('runStart', this.onRunStart.bind(this));
runner.on('testEnd', this.onTestEnd.bind(this));
runner.on('runEnd', this.onRunEnd.bind(this));
}
/**
* Builds an array with the names of nested suites.
*/
babelHelpers.createClass(TapReporter, [{
key: 'onRunStart',
value: function onRunStart(globalSuite) {
console.log('TAP version 13');
}
}, {
key: 'onTestEnd',
value: function onTestEnd(test) {
this.testCount = this.testCount + 1;
}, {
key: 'buildSuiteFullName',
value: function buildSuiteFullName(mochaSuite) {
var fullName = [];
var parent = mochaSuite.parent;
// TODO maybe switch to test.fullName
// @see https://github.com/js-reporters/js-reporters/issues/65
if (test.status === 'passed') {
console.log('ok ' + this.testCount + ' ' + test.testName);
} else if (test.status === 'skipped') {
console.log('ok ' + this.testCount + ' ' + test.testName + ' # SKIP');
} else {
console.log('not ok ' + this.testCount + ' ' + test.testName);
if (!mochaSuite.root) {
fullName.push(mochaSuite.title);
}
test.errors.forEach(function (error) {
console.log(' ---');
console.log(' message: "' + error.toString() + '"');
console.log(' severity: failed');
console.log(' ...');
});
}
}
}, {
key: 'onRunEnd',
value: function onRunEnd(globalSuite) {
console.log('1..' + this.testCount);
}
}], [{
key: 'init',
value: function init(runner) {
return new TapReporter(runner);
}
}]);
return TapReporter;
}();
while (parent && !parent.root) {
fullName.unshift(parent.title);
parent = parent.parent;
}
// TODO: finish grouping once suiteStart is implemented
var hasGrouping = 'group' in console && 'groupEnd' in console;
return fullName;
}
}, {
key: 'onStart',
value: function onStart() {
var globalSuiteStart = this.convertSuite(this.runner.suite);
globalSuiteStart.name = undefined;
var ConsoleReporter = function () {
function ConsoleReporter(runner) {
babelHelpers.classCallCheck(this, ConsoleReporter);
this.emit('runStart', globalSuiteStart);
}
}, {
key: 'onSuite',
value: function onSuite(mochaSuite) {
if (!mochaSuite.root) {
this.emit('suiteStart', this.convertSuite(mochaSuite));
}
}
}, {
key: 'onTest',
value: function onTest(mochaTest) {
this.errors = [];
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);
}
this.emit('testStart', this.convertTest(mochaTest));
}
babelHelpers.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;
}();
/**
* Emits the start of pending tests, because Mocha does not emit skipped tests
* on its "test" event.
*/
/*
The TestReporter verifies that a test runner outputs the right data in the right order.
To do so, it compares the actual output with the provided reference data.
The result is given in the ok attribute.
*/
}, {
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;
var TestReporter = function () {
this.emit('testEnd', this.convertTest(mochaTest));
}
}, {
key: 'onSuiteEnd',
value: function onSuiteEnd(mochaSuite) {
if (!mochaSuite.root) {
this.emit('suiteEnd', this.convertSuite(mochaSuite));
}
}
}, {
key: 'onEnd',
value: function onEnd() {
var globalSuiteEnd = this.convertSuite(this.runner.suite);
globalSuiteEnd.name = undefined;
/**
* @param runner: standardized test runner (or adapter)
* @param referenceData: An array of all expected (eventName, eventData) tuples in the right order
*/
this.emit('runEnd', globalSuiteEnd);
}
}]);
return MochaAdapter;
}(EventEmitter);
function TestReporter(runner, referenceData) {
babelHelpers.classCallCheck(this, TestReporter);
var TapReporter = function () {
function TapReporter(runner) {
classCallCheck(this, TapReporter);
this.referenceData = referenceData.slice();
this.error = false;
runner.on('runStart', this.onEvent.bind(this, 'runStart'));
runner.on('suiteStart', this.onEvent.bind(this, 'suiteStart'));
runner.on('testStart', this.onEvent.bind(this, 'testStart'));
runner.on('testEnd', this.onEvent.bind(this, 'testEnd'));
runner.on('suiteEnd', this.onEvent.bind(this, 'suiteEnd'));
runner.on('runEnd', this.onEvent.bind(this, 'runEnd'));
}
this.testCount = 0;
/**
* Gets called on each event emitted by the runner. Checks if the actual event matches the expected event.
*/
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) {
this.testCount = this.testCount + 1;
babelHelpers.createClass(TestReporter, [{
key: 'onEvent',
value: function onEvent(eventName, eventData) {
var _referenceData$shift = this.referenceData.shift();
// TODO maybe switch to test.fullName
// @see https://github.com/js-reporters/js-reporters/issues/65
if (test.status === 'passed') {
console.log('ok ' + this.testCount + ' ' + test.name);
} else if (test.status === 'skipped') {
console.log('ok ' + this.testCount + ' ' + test.name + ' # SKIP');
} else {
console.log('not ok ' + this.testCount + ' ' + test.name);
var _referenceData$shift2 = babelHelpers.slicedToArray(_referenceData$shift, 2);
test.errors.forEach(function (error) {
console.log(' ---');
console.log(' message: "' + error.toString() + '"');
console.log(' severity: failed');
console.log(' ...');
});
}
}
}, {
key: 'onRunEnd',
value: function onRunEnd(globalSuite) {
console.log('1..' + this.testCount);
}
}], [{
key: 'init',
value: function init(runner) {
return new TapReporter(runner);
}
}]);
return TapReporter;
}();
var expectedEventName = _referenceData$shift2[0];
var expectedEventData = _referenceData$shift2[1];
// TODO: finish grouping once suiteStart is implemented
var hasGrouping = 'group' in console && 'groupEnd' in console;
var ConsoleReporter = function () {
function ConsoleReporter(runner) {
classCallCheck(this, ConsoleReporter);
if (eventName !== expectedEventName || !this.equal(eventData, expectedEventData)) {
this.error = true;
console.error('expected:', expectedEventName, expectedEventData, '\r\n', 'actual:', eventName, eventData);
}
}
}, {
key: 'equal',
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;
}();
/**
* Helper function to compare
* - two Test objects
* - two Suite objects
* - two arrays of Test or Suite objects
* The equality check is not completely strict, e.g. the runtime of a Test does not have to be equal.
* @returns {boolean}: true if both objects are equal, false otherwise
*/
value: function equal(actual, expected) {
if (expected instanceof Suite) {
if (actual.name !== expected.name) {
return false;
}
if (!this.equal(actual.childSuites, expected.childSuites)) {
return false;
}
var index = {
QUnitAdapter: QUnitAdapter,
JasmineAdapter: JasmineAdapter,
MochaAdapter: MochaAdapter,
TapReporter: TapReporter,
ConsoleReporter: ConsoleReporter,
Assertion: Assertion,
Test: Test,
Suite: Suite
};
if (!this.equal(actual.tests, expected.tests)) {
return false;
}
} else if (expected instanceof Test) {
var _arr = ['testName', 'suiteName', 'status'];
return index;
for (var _i = 0; _i < _arr.length; _i++) {
var property = _arr[_i];
if (actual[property] !== expected[property]) {
return false;
}
}
if (typeof actual.runtime !== 'number' && actual.runtime !== undefined) {
return false;
}
if (!(actual.errors === undefined && expected.errors === undefined) && actual.errors.length !== expected.errors.length) {
return false;
}
} else if (Array.isArray(expected)) {
if (actual.length !== expected.length) {
return false;
}
for (var i = 0; i < expected.length; i++) {
if (!this.equal(actual[i], expected[i])) {
return false;
}
}
} else {
return false;
}
return true;
}
}, {
key: 'ok',
get: function get() {
return !this.error && this.referenceData.length === 0;
}
}]);
return TestReporter;
}();
var index = {
QUnitAdapter: QUnitAdapter,
JasmineAdapter: JasmineAdapter,
MochaAdapter: MochaAdapter,
TapReporter: TapReporter,
ConsoleReporter: ConsoleReporter,
TestReporter: TestReporter,
Test: Test,
Suite: Suite
};
return index;
}));

@@ -6,4 +6,3 @@ import QUnitAdapter from './lib/adapters/QUnitAdapter.js'

import ConsoleReporter from './lib/reporters/ConsoleReporter.js'
import TestReporter from './lib/reporters/TestReporter.js'
import {Test, Suite} from './lib/Data.js'
import {Assertion, Test, Suite} from './lib/Data.js'

@@ -16,5 +15,5 @@ export default {

ConsoleReporter,
TestReporter,
Assertion,
Test,
Suite
}
import EventEmitter from 'events'
import { Test, Suite } from '../Data.js'
import {Assertion, Test, Suite} from '../Data.js'

@@ -11,3 +11,7 @@ /**

super()
this.jasmine = jasmine
this.suites = {}
this.tests = {}
jasmine.addReporter({

@@ -21,5 +25,2 @@ jasmineStarted: this.onJasmineStarted.bind(this),

})
this.suites = {}
this.tests = {}
}

@@ -30,2 +31,3 @@

suite.name,
suite.fullName,
suite.childSuites.map(this.createSuiteStart.bind(this)),

@@ -39,2 +41,3 @@ suite.tests.map(this.createTestStart.bind(this))

suite.name,
suite.fullName,
suite.childSuites.map(this.createSuiteEnd.bind(this)),

@@ -46,15 +49,32 @@ suite.tests.map(this.createTestEnd.bind(this))

createTestStart (test) {
return new Test(test.testName, test.suiteName)
return new Test(test.name, test.suiteName, test.fullName)
}
createTestEnd (test) {
return new Test(test.testName, test.suiteName, test.status,
test.runtime, test.errors)
return new Test(test.name, test.suiteName, test.fullName,
test.status, test.runtime, test.errors, test.assertions)
}
createAssertion (expectation) {
let stack = expectation.stack !== '' ? expectation.stack : undefined
return new Assertion(expectation.passed, expectation.actual,
expectation.expected, expectation.message, stack)
}
saveTestDetails (jasmineSpec) {
var test = this.tests[jasmineSpec.id]
test.errors = jasmineSpec.failedExpectations
test.errors = []
test.assertions = []
jasmineSpec.failedExpectations.forEach((expectation) => {
test.errors.push(this.createAssertion(expectation))
test.assertions.push(this.createAssertion(expectation))
})
jasmineSpec.passedExpectations.forEach((expectation) => {
test.assertions.push(this.createAssertion(expectation))
})
if (jasmineSpec.status === 'pending') {

@@ -80,23 +100,24 @@ test.status = 'skipped'

*/
createGlobalSuite (jasmineSuite) {
createGlobalSuite (jasmineSuite, fullName) {
var childSuites = []
var tests = []
var isGlobalSuite = this.isJasmineGlobalSuite(jasmineSuite)
if (!isGlobalSuite) {
fullName.push(jasmineSuite.description)
}
jasmineSuite.children.forEach((child) => {
if (child.id.indexOf('suite') === 0) {
childSuites.push(this.createGlobalSuite(child))
childSuites.push(this.createGlobalSuite(child, fullName))
} else {
let suiteName
let test
let suiteName = !isGlobalSuite ? jasmineSuite.description : undefined
// Jasmine full description is of form "suite1 suite2 ... suiteN test",
// for the "suiteName" property we need to remove test name.
if (!this.isJasmineGlobalSuite(jasmineSuite)) {
suiteName = child.result.fullName.substring(
0, child.result.fullName.indexOf(child.description) - 1
)
}
fullName.push(child.description)
test = new Test(child.description, suiteName)
test = new Test(child.description, suiteName, fullName.slice())
fullName.pop()
tests.push(test)

@@ -107,8 +128,9 @@ this.tests[child.id] = test

let name = (this.isJasmineGlobalSuite(jasmineSuite)) ? undefined
: jasmineSuite.description
let suite = new Suite(name, childSuites, tests)
let name = !isGlobalSuite ? jasmineSuite.description : undefined
let suite = new Suite(name, fullName.slice(), childSuites, tests)
this.suites[jasmineSuite.id] = suite
fullName.pop()
return suite

@@ -118,3 +140,3 @@ }

onJasmineStarted () {
this.globalSuite = this.createGlobalSuite(this.jasmine.topSuite())
this.globalSuite = this.createGlobalSuite(this.jasmine.topSuite(), [])
this.emit('runStart', this.createSuiteStart(this.globalSuite))

@@ -121,0 +143,0 @@ }

import EventEmitter from 'events'
import {Test, Suite} from '../Data.js'
import {Assertion, Test, Suite} from '../Data.js'

@@ -32,2 +32,3 @@ export default class MochaAdapter extends EventEmitter {

mochaSuite.title,
this.buildSuiteFullName(mochaSuite),
mochaSuite.suites.map(this.convertSuite.bind(this)),

@@ -40,5 +41,11 @@ mochaSuite.tests.map(this.convertTest.bind(this))

var suiteName
var fullName
if (!mochaTest.parent.root) {
suiteName = this.buildSuiteName(mochaTest.parent)
suiteName = mochaTest.parent.title
fullName = this.buildSuiteFullName(mochaTest.parent)
// Add also the test name.
fullName.push(mochaTest.title)
} else {
fullName = [mochaTest.title]
}

@@ -50,25 +57,35 @@

var status = (mochaTest.state === undefined) ? 'skipped' : mochaTest.state
let errors = []
// Test end.
return new Test(mochaTest.title, suiteName, status, mochaTest.duration,
mochaTest.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 Test(mochaTest.title, suiteName, fullName, status,
mochaTest.duration, errors, errors)
}
// Test start.
return new Test(mochaTest.title, suiteName)
return new Test(mochaTest.title, suiteName, fullName)
}
/**
* Builds a concatenated name from nested suites.
* Builds an array with the names of nested suites.
*/
buildSuiteName (mochaSuite) {
var suiteName = mochaSuite.title
buildSuiteFullName (mochaSuite) {
var fullName = []
var parent = mochaSuite.parent
while (!parent.root) {
suiteName = parent.title + ' ' + suiteName
if (!mochaSuite.root) {
fullName.push(mochaSuite.title)
}
while (parent && !parent.root) {
fullName.unshift(parent.title)
parent = parent.parent
}
return suiteName
return fullName
}

@@ -75,0 +92,0 @@

import EventEmitter from 'events'
import {Test, Suite} from '../Data.js'
import {Assertion, Test, Suite} from '../Data.js'

@@ -10,2 +10,3 @@ export default class QUnitAdapter extends EventEmitter {

this.tests = {}
this.delim = ' > '

@@ -20,9 +21,21 @@ QUnit.begin(this.onBegin.bind(this))

convertModule (qunitModule) {
var fullName = qunitModule.name.split(this.delim)
.filter((value) => value !== '')
var childSuites = []
return new Suite(
qunitModule.name,
[],
fullName.slice(),
childSuites,
qunitModule.tests.map((qunitTest) => {
let test = new Test(qunitTest.name, qunitModule.name.replace(/> /g, ''))
let indexStart = qunitModule.name.lastIndexOf(this.delim)
indexStart = indexStart === -1 ? 0 : indexStart + this.delim.length
fullName.push(qunitTest.name)
let suiteName = qunitModule.name.substring(indexStart)
let test = new Test(qunitTest.name, suiteName, fullName.slice())
this.tests[qunitTest.testId] = test
fullName.pop()

@@ -38,2 +51,3 @@ return test

test.errors = this.errors
test.assertions = this.assertions

@@ -77,3 +91,3 @@ if (qunitTest.failed > 0) {

} else {
globalSuite = new Suite(undefined, [], [])
globalSuite = new Suite(undefined, [], [], [])
modules = this.QUnit.config.modules

@@ -95,11 +109,12 @@ }

// this means that this suite is the direct child of the global suite.
suites.forEach(function (suite) {
let indexEnd = suite.name.lastIndexOf(' > ')
suites.forEach((suite) => {
let indexEnd = suite.name.lastIndexOf(this.delim)
if (indexEnd !== -1) {
// Find the ' > ' characters that appears before the parent name.
let indexStart = suite.name.substring(0, indexEnd).lastIndexOf(' > ')
let indexStart = suite.name.substring(0, indexEnd)
.lastIndexOf(this.delim)
// If it is -1, the parent suite name starts at 0, else escape
// this characters ' > '.
indexStart = (indexStart === -1) ? 0 : indexStart + 3
indexStart = (indexStart === -1) ? 0 : indexStart + this.delim.length

@@ -109,3 +124,3 @@ var parentSuiteName = suite.name.substring(indexStart, indexEnd)

// Keep only the name of the suite itself.
suite.name = suite.name.substring(indexEnd + 3)
suite.name = suite.name.substring(indexEnd + this.delim.length)

@@ -130,2 +145,3 @@ suites.forEach(function (parentSuite) {

suite.name,
suite.fullName,
suite.childSuites.map(this.createSuiteStart.bind(this)),

@@ -139,2 +155,3 @@ suite.tests.map(this.createTestStart.bind(this))

suite.name,
suite.fullName,
suite.childSuites.map(this.createSuiteEnd.bind(this)),

@@ -146,10 +163,15 @@ suite.tests.map(this.createTestEnd.bind(this))

createTestStart (test) {
return new Test(test.testName, test.suiteName)
return new Test(test.name, test.suiteName, test.fullName)
}
createTestEnd (test) {
return new Test(test.testName, test.suiteName, test.status,
test.runtime, test.errors)
return new Test(test.name, test.suiteName, test.fullName,
test.status, test.runtime, test.errors, test.assertions)
}
createAssertion (qunitTest) {
return new Assertion(qunitTest.result, qunitTest.actual,
qunitTest.expected, qunitTest.message, qunitTest.source || undefined)
}
emitData (suite) {

@@ -174,2 +196,3 @@ suite.tests.forEach((test) => {

this.errors = []
this.assertions = []
}

@@ -179,4 +202,6 @@

if (!details.result) {
this.errors.push(details)
this.errors.push(this.createAssertion(details))
}
this.assertions.push(this.createAssertion(details))
}

@@ -183,0 +208,0 @@

@@ -1,95 +0,139 @@

export class Test {
constructor (testName, suiteName, status, runtime, errors) {
this.testName = testName
this.suiteName = suiteName
this.status = status
this.runtime = runtime
this.errors = errors
}
function getAllTests (suite) {
var childSuiteTests = suite.childSuites
.map((childSuite) => getAllTests(childSuite))
.reduce((allTests, a) => allTests.concat(a), [])
return suite.tests.concat(childSuiteTests)
}
export class Suite {
/**
*
* @param name
* @param childSuites
* @param tests: array containing tests belonging to the suite but not to a child suite
*/
constructor (name, childSuites, tests) {
this.name = name
this.childSuites = childSuites
this.tests = tests
function getRuntime (suite) {
if (suite.status === 'skipped' || suite.status === undefined) {
return undefined
}
getAllTests () {
var childSuiteTests = this.childSuites
.map((suite) => suite.getAllTests())
.reduce((allTests, a) => allTests.concat(a), [])
return getAllTests(suite)
.map((test) => test.status === 'skipped' ? 0 : test.runtime)
.reduce((sum, testRuntime) => sum + testRuntime, 0)
}
return this.tests.concat(childSuiteTests)
}
function getStatus (suite) {
var passed = 0
var failed = 0
var skipped = 0
var tests = getAllTests(suite)
get runtime () {
var status = this.status
for (let i = 0; i < tests.length; i++) {
let test = tests[i]
if (status === 'skipped' || status === undefined) {
// 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 {
failed++
}
}
var runtime = this.getAllTests()
.map((test) => test.status === 'skipped' ? 0 : test.runtime)
.reduce((sum, testRuntime) => sum + testRuntime, 0)
return runtime
if (failed > 0) {
return 'failed'
} else if (skipped > 0 && passed === 0) {
return 'skipped'
} else {
return 'passed'
}
}
get status () {
var passed = 0
var failed = 0
var skipped = 0
var tests = this.getAllTests()
function getTestCounts (suite) {
var tests = getAllTests(suite)
for (let i = 0; i < tests.length; i++) {
let 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 {
failed++
}
// If the suite does not have a status, it means that its tests haven't
// finished to run, so we know only the total.
if (!suite.status) {
return {
passed: undefined,
failed: undefined,
skipped: undefined,
total: tests.length
}
}
if (failed > 0) {
return 'failed'
} else if (skipped > 0 && passed === 0) {
return 'skipped'
} else {
return 'passed'
}
return {
passed: tests.filter((test) => test.status === 'passed').length,
failed: tests.filter((test) => test.status === 'failed').length,
skipped: tests.filter((test) => test.status === 'skipped').length,
total: tests.length
}
}
Object.defineProperties(Suite.prototype, {
toJSON: {
value: function () {
let ret = {}
for (let x in this) {
ret[x] = this[x]
}
return ret
}
},
runtime: {
enumerable: true
},
status: {
enumerable: true
export class Assertion {
/**
* @param {Boolean} passed
* @param {*} actual
* @param {*} expected
* @param {String} message
* @param {String|undefined} stack
*/
constructor (passed, actual, expected, message, stack) {
this.passed = passed
this.actual = actual
this.expected = expected
this.message = message
this.stack = stack
}
})
}
export class Test {
/**
* @param {String} name
* @param {String} suiteName
* @param {String[]} fullName
* @param {String} status
* @param {Number} runtime
* @param {Assertion[]} errors
* @param {Assertion[]} assertions
*/
constructor (name, suiteName, fullName, status, runtime, errors, assertions) {
this.name = name
this.suiteName = suiteName
this.fullName = fullName
this.status = status
this.runtime = runtime
this.errors = errors
this.assertions = assertions
}
}
export class Suite {
/**
* @param {String} name
* @param {String[]} fullName
* @param {Suite[]} childSuites
* @param {Test[]} tests
*/
constructor (name, fullName, childSuites, tests) {
this.name = name
this.fullName = fullName
this.childSuites = childSuites
this.tests = tests
/**
* @type {String}
*/
this.status = getStatus(this)
/**
* @param {Object} testCounts
* @param {Number} testCounts.passed
* @param {Number} testCounts.failed
* @param {Number} testCounts.skipped
* @param {Number} testCounts.total
*/
this.testCounts = getTestCounts(this)
/**
* @type {Number}
*/
this.runtime = getRuntime(this)
}
}

@@ -24,7 +24,7 @@ export default class TapReporter {

if (test.status === 'passed') {
console.log(`ok ${this.testCount} ${test.testName}`)
console.log(`ok ${this.testCount} ${test.name}`)
} else if (test.status === 'skipped') {
console.log(`ok ${this.testCount} ${test.testName} # SKIP`)
console.log(`ok ${this.testCount} ${test.name} # SKIP`)
} else {
console.log(`not ok ${this.testCount} ${test.testName}`)
console.log(`not ok ${this.testCount} ${test.name}`)

@@ -31,0 +31,0 @@ test.errors.forEach(function (error) {

{
"name": "js-reporters",
"version": "1.0.1",
"version": "1.1.0",
"description": "common reporter interface for javascript testing frameworks",

@@ -15,3 +15,3 @@ "main": "dist/js-reporters.js",

"pretest": "npm run build",
"test": "standard && node test/test.js && npm run test-integration && npm run test-unit",
"test": "standard && npm run test-unit && npm run test-integration",
"test-unit": "mocha --recursive test/unit/",

@@ -22,3 +22,4 @@ "test-integration": "mocha test/integration/adapters.js",

"devDependencies": {
"babel-preset-es2015-rollup": "^1.1.1",
"babel-plugin-external-helpers": "^6.8.0",
"babel-preset-es2015": "^6.13.2",
"chai": "^3.5.0",

@@ -32,6 +33,6 @@ "chalk": "^1.1.3",

"qunitjs": "^2.0.0-rc1",
"rollup": "^0.26.0",
"rollup-plugin-babel": "2.4.0",
"rollup-plugin-commonjs": "^2.2.1",
"rollup-plugin-node-resolve": "^1.5.0",
"rollup": "^0.34.1",
"rollup-plugin-babel": "^2.6.1",
"rollup-plugin-commonjs": "^3.3.1",
"rollup-plugin-node-resolve": "^1.7.2",
"sinon": "^1.17.4",

@@ -38,0 +39,0 @@ "sinon-chai": "^2.8.0",

# js-reporters
[![Build Status](https://travis-ci.org/js-reporters/js-reporters.svg?branch=master)](https://travis-ci.org/js-reporters/js-reporters)
[![npm](https://img.shields.io/npm/dm/js-reporters.svg?maxAge=2592000)](https://www.npmjs.com/package/js-reporters)
[![npm](https://img.shields.io/npm/v/js-reporters.svg?maxAge=2592000)](https://www.npmjs.com/package/js-reporters)
[![npm](https://img.shields.io/npm/l/js-reporters.svg?maxAge=2592000)](https://www.npmjs.com/package/js-reporters)
The Common Reporter Interface (CRI) for JavaScript Unit Testing Frameworks

@@ -53,26 +58,57 @@

#### Reporting Order
The recommended **reporting order** for emitting the aformentioned events with their related data should be done in **source order**. Please note that execution order is different from reporting order, that's why we don't assume any specific execution order, but we recommend whatever is higher up in the source file should be emitted first.
For more background check [#62](https://github.com/js-reporters/js-reporters/issues/62).
### Event Data
Based on the discussion in [#12](https://github.com/js-reporters/js-reporters/issues/12#issuecomment-120483356), there are two basic data structures: Suites and Tests. A test represents an atomic test/spec/`it()`. A suite contains tests and optionally other suites. This can represent both flat structures like used by QUnit as well as nested suites like used by Jasmine or Mocha. The data structures are defined as follows:
Based on the discussion in [#12](https://github.com/js-reporters/js-reporters/issues/12#issuecomment-120483356), there are two basic data structures: Suites and Tests. A test represents an atomic test/spec/`it()`. A suite contains tests and optionally other suites.
- **Test**: A test holds basic information on a single test/spec. It has the following set of required attributes:
- `testName`: name of the test
- `suiteName`: name of the suite the test belongs to
- `status`: result of the test. Can `passed`, `failed` or `skipped`. A skipped test is disabled, i.e. it will not be executed.
- `runtime`: execution time in milliseconds
- `errors`: array containing all errors. Depending on the framework, this is a single exception or a list of failed assertions. Will be empty for statuses other than failed.
- **Suite**: A suite is a collection of tests and potentially other suites.
- `name`: name of the suite
- `childSuites`: array with all direct subsuites
- `tests`: array containing all tests that directly belong to the suite (but not to a child suite)
- `runtime`: execution time of the whole suite in milliseconds (including child suites)
- `status`: summarized status of the suite
- `failed`, if at least one test failed
- `skipped`, if all tests in the suite are skipped (and there is at least one skipped test)
- `passed`, if there is at least one passed test and all other tests are skipped or if there are no tests in the suite.
For `testStart` and `testEnd`, the corresponding test object is passed to the reporter. The same applies to `suiteStart` and `suiteEnd` where the matching suite object is passed to the reporter. For `runStart` and `runEnd` a "global" suite object is passed to the reporter, this suite wraps all other top-level user defined suites as its child suites, it will be reffered to as `globalSuite`.
The data structures are defined as follows:
- **Suite**: `Object` - A suite is a collection of tests and potentially other suites.
- **name**: `String|undefined` - name of the suite, will be `undefined` only for the `globalSuite`.
- **fullname**: `Array` - array of strings containing the name of the suite and the names of all its suites ancestors.
- **tests**: `Array` - array containing all tests that directly belong to the suite (but not to a child suite).
- **childSuites**: `Array` - array with all direct subsuites.
- **status**: `String|undefined` - summarized status of the suite, it will be `undefined` on the `suiteStart` and `runStart` event.
- `failed`, if at least one test in the suite or in its child suites has failed.
- `skipped`, if all tests in the suite and in its child suites are skipped (and there is at least one skipped test).
- `passed`, if there is at least one passed test in the suite or in its child suites and all other tests are skipped or if there are no tests in the suite.
- **testCounts**: `Object` - contains how many tests have passed, failed etc. including the tests of child suites.
- **passed**: `Number|undefined` - number of passed tests, it will be `undefined` for the `runStart` and `suiteStart` event.
- **failed**: `Number|undefined` - number of failed tests, it will be `undefined` for the `runStart` and `suiteStart` event.
- **skipped**: `Number|undefined` - number of skipped tests, it will be `undefined` for the `runStart` and `suiteStart` event.
- **total**: `Number` - total number of tests, the sum of the above 3 properties must equal this one.
- **runtime**: `Number|undefined` - execution time of the whole suite in milliseconds (including child suites), it will be `undefined` on the `suiteStart` and `runStart` event.
For `testStart` and `testEnd`, the corresponding test object is passed to the reporter. The same applies to `suiteStart` and `suiteEnd` where the matching suite object is passed to the reporter. For `runStart` and `runEnd` a "global" suite object is passed to the reporter, which contains all top-level suites as child suites.
The above `suite properties` apply also for the `globalSuite`.
When `runStart`, `suiteStart` and `testStart` are emitted, the `status`, `runtime` and `errors` attributes are `undefined`.
- **Test**: `Object` - A test holds basic information on a single test/spec.
- **name**: `String` - name of the test.
- **suiteName**: `String` - name of the suite the test belongs to.
- **fullName**: `Array` - array of strings containing the name of the test and the names of all its suites ancestors.
- **status**: `String|undefined` - result of the test, it will be `undefined` for the `testStart` event. Can be:
- `passed`, if all assertions have passed.
- `failed`, if at least one assertion has failed.
- `skipped`, if the test is disabled and wasn't executed.
- **runtime**: `Number|undefined` - execution time in milliseconds, it will be `undefined` for the `testStart` event.
- **errors**: `Array|undefined` - array containing all errors, i.e failed Assertions, it will be `undefined` for the `testStart` event. It will contain at least one error for failed statuses and it will be empty for statuses other than failed.
- **assertions**: `Array|undefined` - array of Assertions containing all assertions passed and failed, for a skipped test there will be an empty array, it will be `undefined` for the `testStart` event. Frameworks that don't track passed assertions can always provide an empty array for passed tests. In that case, for failed tests this should match the errors property.
Based on the discussion in [#79](https://github.com/js-reporters/js-reporters/issues/79), js-reporters establishes also a minimum set of properties for the emitted assertions, failed or passed:
- **Assertion**: `Object` - An object which contains information of a single assertion/expectation.
- **passed**: `Boolean` - `true` for a passed assertion, `failed` for a failed assertion.
- **actual**: `*` - the actual value passed to the assertion, should coincide with `expected` for passed assertions.
- **expected**: `*` - the expected value passed to the assertion, should coincide with `actual` for passed assertions.
- **message**: `String` - a description.
- **stack**: `String|undefined` - represents the stack trace for a failed assertion, for a `passed` one it is `undefined`.
Additional properties (not defined here) can be added to the Assertion object.
## Cross-Reference Issues

@@ -79,0 +115,0 @@

@@ -1,5 +0,5 @@

/* global describe, it, xit */
/* global describe, it, xit, expect */
it('global test', function () {
expect(true).toBeTruthy()
})

@@ -9,3 +9,3 @@

it('should pass', function () {
expect(true).toBeTruthy()
})

@@ -28,3 +28,3 @@ })

it('should pass', function () {
expect(true).toBeTruthy()
})

@@ -43,3 +43,3 @@

it('outter test', function () {
expect(true).toBeTruthy()
})

@@ -49,5 +49,5 @@

it('inner test', function () {
expect(true).toBeTruthy()
})
})
})

@@ -15,3 +15,5 @@ /* eslint-env mocha */

// Attaches the event handler for the runner events.
/**
* Attaches the event handler for the runner events.
*/
function _attachListeners (done, runner) {

@@ -30,3 +32,5 @@ var dummyFunc = function () {}

// Recursively iterate over each suite and set their tests runtime to 0ms.
/**
* Recursively iterate over each suite and set their tests runtime to 0ms.
*/
function _setSuiteTestsRuntime (suite) {

@@ -44,19 +48,138 @@ suite.tests.forEach(function (test) {

// Recursively iterate over each suite and overwrite its errors.
function _overWriteTestsErrors (suite) {
/**
* Set the suites runtime to 0 to match the runtime of the refrence suites.
*/
function _setSuitesRuntime (suite) {
if (suite.status !== 'skipped') {
suite.runtime = 0
}
suite.childSuites.forEach(function (childSuite) {
_setSuitesRuntime(childSuite)
})
}
/**
* Overwrite test assertions (for test frameworks that provide this) so that
* they will match match those from the refrence-data file.
*/
function _overWriteTestAssertions (test) {
test.errors.forEach(function (error) {
error.actual = undefined
error.expected = undefined
error.message = undefined
error.stack = undefined
})
test.assertions.forEach(function (assertion) {
assertion.actual = undefined
assertion.expected = undefined
assertion.message = undefined
assertion.stack = undefined
})
}
/**
* Recursively iterates over suites and overwrites tests assertions. Check
* also _overWriteTestNormalizedAssertions function.
*/
function _overWriteSuitesAssertions (suite) {
suite.tests.forEach(function (test) {
if (test.status === 'failed') {
test.errors = [new Error('error')]
}
_overWriteTestAssertions(test)
})
suite.childSuites.forEach(function (childSuite) {
_overWriteTestsErrors(childSuite)
_overWriteSuitesAssertions(childSuite)
})
}
/**
* Fills the assertions and error properties with assertions so that they will
* match with those from the data-refrence file, also as content as also as
* number of contained assertions.
*/
function _fillTestAssertions (refTest, test) {
test.assertions = []
test.errors = []
refTest.assertions.forEach(function (assertion) {
test.assertions.push(assertion)
})
refTest.errors.forEach(function (error) {
test.errors.push(error)
})
}
/**
* Recursively iterates over suites and fills with assertions. Check also
* _fillTestAssertins function.
*/
function _fillSuiteAssertions (refSuite, suite) {
refSuite.tests.forEach(function (refTest, index) {
_fillTestAssertions(refTest, suite.tests[index])
})
refSuite.childSuites.forEach(function (childSuite, index) {
_fillSuiteAssertions(childSuite, suite.childSuites[index])
})
}
/**
* Counts tests for the "suiteStart" and "runStart" event.
*/
function getTestCountsStart (refSuite) {
var testCounts = {
passed: undefined,
failed: undefined,
skipped: undefined,
total: refSuite.tests.length
}
refSuite.childSuites.forEach(function (childSuite) {
testCounts.total += getTestCountsStart(childSuite).total
})
return testCounts
}
/**
* Counts tests for the "suiteEnd" and "runEnd" event.
*/
function getTestCountsEnd (refSuite) {
var testCounts = {
passed: 0,
failed: 0,
skipped: 0,
total: refSuite.tests.length
}
testCounts.passed += refSuite.tests.filter(function (test) {
return test.status === 'passed'
}).length
testCounts.failed += refSuite.tests.filter(function (test) {
return test.status === 'failed'
}).length
testCounts.skipped += refSuite.tests.filter(function (test) {
return test.status === 'skipped'
}).length
refSuite.childSuites.forEach(function (childSuite) {
var childTestCounts = getTestCountsEnd(childSuite)
testCounts.passed += childTestCounts.passed
testCounts.failed += childTestCounts.failed
testCounts.skipped += childTestCounts.skipped
testCounts.total += childTestCounts.total
})
return testCounts
}
describe('Adapters integration', function () {
Object.keys(runAdapters).forEach(function (adapter) {
describe(adapter + ' adapter', function () {
var testDescription
var keys = ['passed', 'actual', 'expected', 'message', 'stack']

@@ -76,52 +199,87 @@ before(function (done) {

if (adapter === 'QUnit') {
it('tests errors should be QUnit errors like', function () {
collectedData.forEach(function (value) {
if (value[0] === 'testEnd' && value[1].status === 'failed') {
// The runtime must be the one from the error not from the test,
// @see http://api.qunitjs.com/QUnit.log/ and
// http://api.qunitjs.com/QUnit.testDone/.
var error = {
actual: null,
message: value[1].errors[0].message,
module: value[1].suiteName,
name: value[1].testName,
result: false,
runtime: value[1].errors[0].runtime,
source: 'Error: error',
testId: value[1].errors[0].testId
}
it('testing tests errors prop', function () {
var refTestsEnd = refData.filter(function (value) {
return value[0] === 'testEnd'
})
expect(value[1].errors).to.be.deep.equal([error])
}
})
var testsEnd = collectedData.filter(function (value) {
return value[0] === 'testEnd'
})
}
if (adapter === 'Jasmine') {
it('tests errors should be Jasmine errors like', function () {
collectedData.forEach(function (value) {
if (value[0] === 'testEnd' && value[1].status === 'failed') {
var error = {
matcherName: '',
message: 'Error: error',
stack: value[1].errors[0].stack,
passed: false,
expected: '',
actual: ''
}
refTestsEnd.forEach(function (value, index) {
var refTest = value[1]
var test = testsEnd[index][1]
expect(value[1].errors).to.be.deep.equal([error])
}
if (refTest.status === 'passed' || refTest.status === 'skipped') {
expect(test.errors).to.be.deep.equal(refTest.errors)
} else {
expect(test.errors).to.have.lengthOf(refTest.errors.length)
test.errors.forEach(function (error) {
expect(error).to.have.all.keys(keys)
expect(error.passed).to.be.false
expect(error.message).to.be.a('string')
expect(error.stack).to.be.a('string')
})
}
})
})
it('testing tests assertions prop', function () {
var refTestsEnd = refData.filter(function (value) {
return value[0] === 'testEnd'
})
var testsEnd = collectedData.filter(function (value) {
return value[0] === 'testEnd'
})
refTestsEnd.forEach(function (value, index) {
var refTest = value[1]
var test = testsEnd[index][1]
// Expect to contain the correct number of assertions, only for
// test frameworks that provide all assertions.
if (adapter !== 'Mocha') {
expect(test.assertions).to.have.lengthOf(refTest.assertions.length)
}
var passedAssertions = test.assertions.filter(function (assertion) {
return assertion.passed
})
var failedAssertions = test.assertions.filter(function (assertion) {
return !assertion.passed
})
passedAssertions.forEach(function (assertion) {
expect(assertion).to.have.all.keys(keys)
expect(assertion.passed).to.be.true
expect(assertion.message).to.be.a('string')
expect(assertion.stack).to.be.undefined
})
failedAssertions.forEach(function (assertion) {
expect(assertion).to.have.all.keys(keys)
expect(assertion.passed).to.be.false
expect(assertion.message).to.be.a('string')
expect(assertion.stack).to.be.a('string')
})
})
}
})
refData.forEach(function (value, index) {
testDescription = value[2]
var testDescription = value[2]
it(testDescription, function () {
var refEvent = value[0]
var refTestItem = value[1]
var event = collectedData[index][0]
var testItem = collectedData[index][1]
// Set tests runtime to 0 to match the reference tests runtime.
if (collectedData[index][0] === 'testEnd' &&
collectedData[index][1].status !== 'skipped') {
if (event === 'testEnd' && testItem.status !== 'skipped') {
collectedData[index][1].runtime = 0

@@ -131,40 +289,53 @@ }

// Set suite tests runtime to 0, also for the globalSuite.
if (collectedData[index][0] === 'suiteEnd' ||
collectedData[index][0] === 'runEnd') {
if (event === 'suiteEnd' || event === 'runEnd') {
_setSuiteTestsRuntime(collectedData[index][1])
}
// Overwrite QUnit/Jasmine error of failed tests with standard error.
if ((adapter === 'QUnit' || adapter === 'Jasmine') &&
collectedData[index][0] === 'testEnd' &&
collectedData[index][1].status === 'failed') {
collectedData[index][1].errors = [new Error()]
// Set assertions to match those from data-refrence file.
if (event === 'testEnd') {
if (adapter === 'Mocha') {
_fillTestAssertions(refTestItem, testItem)
} else {
_overWriteTestAssertions(testItem)
}
}
// Overwrite suite QUnit/Jasmine errors with standard errors.
if ((adapter === 'QUnit' || adapter === 'Jasmine') &&
(collectedData[index][0] === 'suiteEnd' ||
collectedData[index][0] === 'runEnd')) {
_overWriteTestsErrors(collectedData[index][1])
// Set assertions to match thos from the data-refrence file.
if (event === 'suiteEnd' || event === 'runEnd') {
if (adapter === 'Mocha') {
_fillSuiteAssertions(refTestItem, testItem)
} else {
_overWriteSuitesAssertions(testItem)
}
}
expect(collectedData[index][0]).equal(value[0])
expect(collectedData[index][1]).to.be.deep.equal(value[1])
// Verify suite self-setting props.
if (event === 'suiteStart' || event === 'runStart') {
expect(testItem.status).to.be.undefined
expect(testItem.runtime).to.be.undefined
// Verify the dynamic props.
if (value[0] === 'suiteStart' || value[0] === 'runStart') {
expect(collectedData[index][1].status).to.be.undefined
expect(collectedData[index][1].runtime).to.be.undefined
expect(testItem.testCounts).to.be.deep
.equal(getTestCountsStart(refTestItem))
}
// Verify the dynamic props.
if (value[0] === 'suiteEnd' || value[0] === 'runEnd') {
expect(collectedData[index][1].status).to.be.equal(value[3])
// Verify suite self-setting props.
if (event === 'suiteEnd' || event === 'runEnd') {
var refStatus = value[3]
if (collectedData[index][1].status !== 'skipped') {
expect(collectedData[index][1].runtime).to.be.a('number')
expect(testItem.status).to.be.equal(refStatus)
if (testItem.status !== 'skipped') {
expect(testItem.runtime).to.be.a('number')
// Set suites runtime to 0, to pass the deep equal assertion.
_setSuitesRuntime(testItem)
} else {
expect(collectedData[index][1].runtime).to.be.undefined
expect(testItem.runtime).to.be.undefined
}
expect(testItem.testCounts).to.be.deep
.equal(getTestCountsEnd(refTestItem))
}
expect(event).equal(refEvent)
expect(testItem).to.be.deep.equal(refTestItem)
})

@@ -171,0 +342,0 @@ })

@@ -5,61 +5,101 @@ var JsReporters = require('../../dist/js-reporters.js')

var globalTestStart = new Test('global test', undefined, undefined, undefined,
undefined)
var globalTestEnd = new Test('global test', undefined, 'passed', 0, [])
var noErrors = []
var noAssertions = []
/**
* All props are undefined, except "passed", because we don't know what they
* will contain, which is depending from framework to framework. The props are
* anyway verified one by one, see "adapters.js" file.
*/
var errors = [{
passed: false,
actual: undefined,
expected: undefined,
message: undefined,
stack: undefined
}]
var failedAssertions = [{
passed: false,
actual: undefined,
expected: undefined,
message: undefined,
stack: undefined
}]
var passedAssertions = [{
passed: true,
actual: undefined,
expected: undefined,
message: undefined,
stack: undefined
}]
var globalTestStart = new Test('global test', undefined, ['global test'],
undefined, undefined, undefined)
var globalTestEnd = new Test('global test', undefined, ['global test'],
'passed', 0, noErrors, passedAssertions)
var passingTestStart1 = new Test('should pass', 'suite with passing test',
undefined, undefined, undefined)
['suite with passing test', 'should pass'], undefined, undefined, undefined)
var passingTestEnd1 = new Test('should pass', 'suite with passing test',
'passed', 0, [])
['suite with passing test', 'should pass'], 'passed', 0, noErrors,
passedAssertions)
var passingTestStart2 = new Test('should pass', 'suite with tests',
undefined, undefined, undefined)
var passingTestEnd2 = new Test('should pass', 'suite with tests', 'passed',
0, [])
['suite with tests', 'should pass'], undefined, undefined, undefined)
var passingTestEnd2 = new Test('should pass', 'suite with tests',
['suite with tests', 'should pass'], 'passed', 0, noErrors,
passedAssertions)
var skippedTestStart1 = new Test('should skip', 'suite with skipped test',
undefined, undefined, undefined)
['suite with skipped test', 'should skip'], undefined, undefined, undefined)
var skippedTestEnd1 = new Test('should skip', 'suite with skipped test',
'skipped', undefined, [])
['suite with skipped test', 'should skip'], 'skipped', undefined, noErrors,
noAssertions)
var skippedTestStart2 = new Test('should skip', 'suite with tests',
undefined, undefined, undefined)
var skippedTestEnd2 = new Test('should skip', 'suite with tests', 'skipped',
undefined, [])
['suite with tests', 'should skip'], undefined, undefined, undefined)
var skippedTestEnd2 = new Test('should skip', 'suite with tests',
['suite with tests', 'should skip'], 'skipped', undefined, noErrors,
noAssertions)
var failingTestStart1 = new Test('should fail', 'suite with failing test',
undefined, undefined, undefined)
var failingTestEnd1 = new Test('should fail', 'suite with failing test', 'failed',
0, [new Error('error')])
['suite with failing test', 'should fail'], undefined, undefined, undefined)
var failingTestEnd1 = new Test('should fail', 'suite with failing test',
['suite with failing test', 'should fail'], 'failed', 0, errors,
failedAssertions)
var failingTestStart2 = new Test('should fail', 'suite with tests',
undefined, undefined, undefined)
var failingTestEnd2 = new Test('should fail', 'suite with tests', 'failed',
0, [new Error('error')])
['suite with tests', 'should fail'], undefined, undefined, undefined)
var failingTestEnd2 = new Test('should fail', 'suite with tests',
['suite with tests', 'should fail'], 'failed', 0, errors,
failedAssertions)
var innerTestStart = new Test('inner test', 'outter suite inner suite',
undefined, undefined, undefined)
var innerTestEnd = new Test('inner test', 'outter suite inner suite',
'passed', 0, [])
var innerTestStart = new Test('inner test', 'inner suite', ['outter suite',
'inner suite', 'inner test'], undefined, undefined, undefined)
var innerTestEnd = new Test('inner test', 'inner suite', ['outter suite',
'inner suite', 'inner test'], 'passed', 0, noErrors, passedAssertions)
var outterTestStart = new Test('outter test', 'outter suite',
undefined, undefined, undefined)
var outterTestEnd = new Test('outter test', 'outter suite', 'passed', 0, [])
var outterTestStart = new Test('outter test', 'outter suite', ['outter suite',
'outter test'], undefined, undefined, undefined)
var outterTestEnd = new Test('outter test', 'outter suite', ['outter suite',
'outter test'], 'passed', 0, noErrors, passedAssertions)
var passingSuiteStart = new Suite('suite with passing test', [],
[passingTestStart1])
var passingSuiteEnd = new Suite('suite with passing test', [],
[passingTestEnd1])
var passingSuiteStart = new Suite('suite with passing test',
['suite with passing test'], [], [passingTestStart1])
var passingSuiteEnd = new Suite('suite with passing test',
['suite with passing test'], [], [passingTestEnd1])
var skippedSuiteStart = new Suite('suite with skipped test', [],
[skippedTestStart1])
var skippedSuiteEnd = new Suite('suite with skipped test', [],
[skippedTestEnd1])
var skippedSuiteStart = new Suite('suite with skipped test',
['suite with skipped test'], [], [skippedTestStart1])
var skippedSuiteEnd = new Suite('suite with skipped test',
['suite with skipped test'], [], [skippedTestEnd1])
var failingSuiteStart = new Suite('suite with failing test', [],
[failingTestStart1])
var failingSuiteEnd = new Suite('suite with failing test', [],
[failingTestEnd1])
var failingSuiteStart = new Suite('suite with failing test',
['suite with failing test'], [], [failingTestStart1])
var failingSuiteEnd = new Suite('suite with failing test',
['suite with failing test'], [], [failingTestEnd1])
var testSuiteStart = new Suite('suite with tests', [], [
var testSuiteStart = new Suite('suite with tests', ['suite with tests'], [], [
passingTestStart2,

@@ -69,3 +109,3 @@ skippedTestStart2,

])
var testSuiteEnd = new Suite('suite with tests', [], [
var testSuiteEnd = new Suite('suite with tests', ['suite with tests'], [], [
passingTestEnd2,

@@ -76,11 +116,13 @@ skippedTestEnd2,

var innerSuiteStart = new Suite('inner suite', [], [innerTestStart])
var innerSuiteEnd = new Suite('inner suite', [], [innerTestEnd])
var innerSuiteStart = new Suite('inner suite', ['outter suite', 'inner suite'],
[], [innerTestStart])
var innerSuiteEnd = new Suite('inner suite', ['outter suite', 'inner suite'],
[], [innerTestEnd])
var outterSuiteStart = new Suite('outter suite', [innerSuiteStart],
[outterTestStart])
var outterSuiteEnd = new Suite('outter suite', [innerSuiteEnd],
[outterTestEnd])
var outterSuiteStart = new Suite('outter suite', ['outter suite'],
[innerSuiteStart], [outterTestStart])
var outterSuiteEnd = new Suite('outter suite', ['outter suite'],
[innerSuiteEnd], [outterTestEnd])
var globalSuiteStart = new Suite(undefined, [
var globalSuiteStart = new Suite(undefined, [], [
passingSuiteStart,

@@ -92,3 +134,3 @@ skippedSuiteStart,

], [globalTestStart])
var globalSuiteEnd = new Suite(undefined, [
var globalSuiteEnd = new Suite(undefined, [], [
passingSuiteEnd,

@@ -95,0 +137,0 @@ skippedSuiteEnd,

var Test = require('../../dist/js-reporters.js').Test
module.exports = {
passingTest: new Test('pass', undefined, 'passed', 0, []),
failingTest: new Test('fail', undefined, 'failed', 0, [
passingTest: new Test('pass', undefined, [], 'passed', 0, []),
failingTest: new Test('fail', undefined, [], 'failed', 0, [
new Error('first error'), new Error('second error')
]),
skippedTest: new Test('skip', undefined, 'skipped', 0, [])
skippedTest: new Test('skip', undefined, [], 'skipped', 0, [])
}

@@ -30,3 +30,3 @@ /* eslint-env mocha */

var spy = this.stub(console, 'log')
var expected = 'ok 1 ' + data.passingTest.testName
var expected = 'ok 1 ' + data.passingTest.name

@@ -40,3 +40,3 @@ emitter.emit('testEnd', data.passingTest)

var spy = this.stub(console, 'log')
var expected = 'ok 2 ' + data.skippedTest.testName + ' # SKIP'
var expected = 'ok 2 ' + data.skippedTest.name + ' # SKIP'

@@ -50,3 +50,3 @@ emitter.emit('testEnd', data.skippedTest)

var spy = this.stub(console, 'log')
var expected = 'not ok 3 ' + data.failingTest.testName
var expected = 'not ok 3 ' + data.failingTest.name

@@ -53,0 +53,0 @@ emitter.emit('testEnd', data.failingTest)

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc