kocha
Version:
Modern, simpler Mocha clone, no globals, lint friendly
206 lines (172 loc) • 6.03 kB
JavaScript
'use strict';
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; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(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; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var EventEmitter = require('events').EventEmitter;
var wait = function wait(dur) {
return new Promise(function (resolve) {
return setTimeout(resolve, dur);
});
};
/**
* @param {Function} cb The callback function
* @return {boolean}
*/
var isAsyncCb = function isAsyncCb(cb) {
return cb.length > 0;
};
/**
* @param {Function} func The callback function
* @param {Function} onDoubleCall The callback for double call
* @return {Promise}
*/
var runAsyncCb = function runAsyncCb(func, onDoubleCall) {
return new Promise(function (resolve, reject) {
var doneCalledCount = 0;
var done = function done(result) {
doneCalledCount += 1;
if (doneCalledCount === 2) {
return onDoubleCall();
}
if (doneCalledCount > 2) {
// Ignores excessive calls of done
return;
}
if (result instanceof Error) {
return reject(result);
}
if (result) {
return reject(new Error('done() invoked with non-Error: ' + result));
}
resolve();
};
func(done);
});
};
/**
* @param {Function} cb The callback function
* @param {Function} onDoubleCall The callback for double call
* @return {Promise}
*/
var runCb = function runCb(cb, onDoubleCall) {
if (isAsyncCb(cb)) {
return runAsyncCb(cb, onDoubleCall);
}
try {
return Promise.resolve(cb());
} catch (e) {
return Promise.reject(e);
}
};
var throwAfterTimeout = function throwAfterTimeout(timeout) {
return wait(timeout).then(function () {
throw new Error('Timeout of ' + timeout + 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.');
});
};
var TestNode = function (_EventEmitter) {
_inherits(TestNode, _EventEmitter);
/**
* @param {string} title The title of the test suite
* @param {boolean} skipped True iff the suite is skipped
* @param {Suite} parent The parent suite
*/
function TestNode(title, skipped, parent) {
_classCallCheck(this, TestNode);
var _this = _possibleConstructorReturn(this, (TestNode.__proto__ || Object.getPrototypeOf(TestNode)).call(this));
_this.title = title;
_this.skipped = skipped;
_this.parent = parent;
_this.root = parent == null; // True if root suite
_this.timeoutDuration = null;
_this.retryCount = 0;
return _this;
}
/**
* Returns true if skipped node.
* @return {boolean}
*/
_createClass(TestNode, [{
key: 'isSkipped',
value: function isSkipped() {
if (this.parent) {
return this.skipped || this.parent.isSkipped();
}
return this.skipped;
}
}, {
key: 'getRunner',
value: function getRunner() {
return this.parent ? this.parent.getRunner() : this;
}
/**
* Gets the retry count.
* @return {number}
*/
}, {
key: 'getRetryCount',
value: function getRetryCount() {
if (this.parent) {
return this.retryCount || this.parent.getRetryCount();
}
return this.retryCount;
}
/**
* Sets the retry count.
* @param {number} n The retry count
*/
}, {
key: 'setRetryCount',
value: function setRetryCount(n) {
this.retryCount = n;
}
/**
* Bubbles the event to the parent suite.
* @param {string} event The event name
* @param {any} arg The argument
* @param {Error?} err The error object
*/
}, {
key: 'bubbleEvent',
value: function bubbleEvent(event, arg, err) {
if (this.parent) {
this.parent.bubbleEvent(event, arg, err);
} else if (err) {
this.emit(event, arg, err);
} else if (arg) {
this.emit(event, arg);
} else {
this.emit(event);
}
}
}, {
key: 'setTimeout',
value: function setTimeout(timeout) {
this.timeoutDuration = timeout;
}
/**
* Returns the timeout of the node.
* @return {number}
*/
}, {
key: 'getTimeout',
value: function getTimeout() {
return typeof this.timeoutDuration === 'number' ? this.timeoutDuration : this.parent.getTimeout();
}
/**
* Returns the full title including the parent's title.
*/
}, {
key: 'fullTitle',
value: function fullTitle() {
if (this.parent.root) {
return this.title;
}
return this.parent.fullTitle() + ' ' + this.title;
}
}]);
return TestNode;
}(EventEmitter);
module.exports = TestNode;
module.exports.runCb = runCb;
module.exports.throwAfterTimeout = throwAfterTimeout;