intern
Version:
Intern. A next-generation code testing stack for JavaScript.
314 lines • 11.8 kB
JavaScript
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "tslib", "@theintern/common", "./Deferred", "./common/util", "./common/time"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SKIP = exports.isTestFunction = exports.isTestOptions = exports.isTest = void 0;
var tslib_1 = require("tslib");
var common_1 = require("@theintern/common");
var Deferred_1 = tslib_1.__importDefault(require("./Deferred"));
var util_1 = require("./common/util");
var time_1 = require("./common/time");
var Test = (function () {
function Test(options) {
var _this = this;
this._hasPassed = false;
this._isAsync = false;
this._usesRemote = false;
if (!options.name || !options.test) {
throw new Error('A Test requires a name and a test function');
}
['timeElapsed', 'hasPassed'].forEach(function (property) {
var name = property;
if (options[name] != null) {
_this["_" + name] = options[name];
}
delete options[name];
});
Object.assign(this, options);
}
Object.defineProperty(Test.prototype, "executor", {
get: function () {
return this.parent && this.parent.executor;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Test.prototype, "hasPassed", {
get: function () {
return this._hasPassed;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Test.prototype, "id", {
get: function () {
var name = [];
var suiteOrTest = this;
do {
suiteOrTest.name != null && name.unshift(suiteOrTest.name);
} while ((suiteOrTest = suiteOrTest.parent));
return name.join(' - ');
},
enumerable: false,
configurable: true
});
Object.defineProperty(Test.prototype, "isAsync", {
get: function () {
return this._isAsync;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Test.prototype, "parentId", {
get: function () {
return this.parent.id;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Test.prototype, "remote", {
get: function () {
this._usesRemote = true;
return this.parent.remote;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Test.prototype, "sessionId", {
get: function () {
return this.parent.sessionId;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Test.prototype, "timeElapsed", {
get: function () {
return this._timeElapsed;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Test.prototype, "timeout", {
get: function () {
if (this._timeout != null) {
return this._timeout;
}
if (this.parent && this.parent.timeout != null) {
return this.parent.timeout;
}
return 30000;
},
set: function (value) {
this._timeout = value;
},
enumerable: false,
configurable: true
});
Test.prototype.async = function (timeout, numCallsUntilResolution) {
this._isAsync = true;
if (timeout != null) {
this.timeout = timeout;
}
var remainingCalls = numCallsUntilResolution || 1;
var dfd = new Deferred_1.default();
var oldResolve = dfd.resolve;
dfd.resolve = function (value) {
--remainingCalls;
if (remainingCalls === 0) {
oldResolve.call(this, value);
}
else if (remainingCalls < 0) {
throw new Error('resolve called too many times');
}
};
this.async = function () {
return dfd;
};
return dfd;
};
Test.prototype.restartTimeout = function (timeout) {
var _this = this;
if (timeout != null) {
this.timeout = timeout;
}
if (this._runTask) {
if (this._timer) {
time_1.clearTimeout(this._timer);
}
this._timer = time_1.setTimeout(function () {
_this._timer = undefined;
if (_this._runTask) {
var error = new Error("Timeout reached on " + _this.id + "#");
error.name = 'TimeoutError';
_this.error = error;
_this._runTask.cancel();
}
}, this.timeout);
}
};
Test.prototype.run = function () {
var _this = this;
var startTime;
if (this._runTask) {
this._runTask.cancel();
this._runTask = undefined;
}
if (this._timer) {
time_1.clearTimeout(this._timer);
this._timer = undefined;
}
this._usesRemote = false;
this._hasPassed = false;
this._isAsync = false;
this._timeElapsed = 0;
this._runTask = undefined;
this.async = Object.getPrototypeOf(this).async;
this.error = undefined;
this.skipped = undefined;
return this.executor
.emit('testStart', this)
.then(function () {
startTime = time_1.now();
})
.then(function () {
var result = _this.test(_this);
if (_this.isAsync) {
if (!common_1.isPromiseLike(result)) {
result = _this.async().promise;
}
else {
result = common_1.Task.race([_this.async().promise, result]);
}
}
if (common_1.isPromiseLike(result)) {
_this._isAsync = true;
return new common_1.Task(function (resolve, reject) {
_this._runTask = new common_1.Task(function (resolve, reject) {
var settled = false;
if (common_1.isPromiseLike(result)) {
result.then(function () {
settled = true;
resolve();
}, function (error) {
settled = true;
reject(error);
});
}
if (common_1.isTask(result)) {
result
.finally(function () {
if (!settled) {
_this.skipped = 'Canceled';
reject(exports.SKIP);
}
})
.catch(function (_error) { });
}
}, function () {
if (common_1.isTask(result)) {
result.cancel();
}
if (_this.error) {
reject(_this.error);
}
}).then(function () {
resolve();
}, reject);
_this.restartTimeout();
});
}
})
.finally(function () {
if (_this._runTask) {
_this._runTask.cancel();
}
_this._runTask = undefined;
_this._timeElapsed = time_1.now() - startTime;
if (_this._timer) {
time_1.clearTimeout(_this._timer);
_this._timer = undefined;
}
})
.then(function () {
if (_this._usesRemote && !_this.isAsync) {
throw new Error('Remote used in synchronous test! Tests using this.remote must ' +
'return a promise or resolve a this.async deferred.');
}
_this._hasPassed = true;
})
.catch(function (error) {
if (error === exports.SKIP) {
if (!_this.skipped) {
var parentSkipped = _this.parent && _this.parent.skipped;
_this.skipped = parentSkipped || 'suite skipped';
}
}
else {
_this.error = error;
throw error;
}
})
.finally(function () { return _this.executor.emit('testEnd', _this); });
};
Test.prototype.skip = function (message) {
if (message === void 0) { message = 'skipped'; }
this.skipped = message;
throw exports.SKIP;
};
Test.prototype.toJSON = function () {
var _this = this;
var json = {};
var properties = [
'id',
'parentId',
'name',
'sessionId',
'timeElapsed',
'timeout',
'hasPassed',
'skipped'
];
properties.forEach(function (key) {
var value = _this[key];
if (typeof value !== 'undefined') {
json[key] = value;
}
});
if (this.suiteError) {
json.suiteError = util_1.errorToJSON(this.suiteError);
}
if (this.error) {
json.error = util_1.errorToJSON(this.error);
}
return json;
};
return Test;
}());
exports.default = Test;
function isTest(value) {
return (value != null &&
typeof value.test === 'function' &&
typeof value.hasPassed === 'boolean');
}
exports.isTest = isTest;
function isTestOptions(value) {
return (value != null &&
!(value instanceof Test) &&
value.name != null &&
value.test != null);
}
exports.isTestOptions = isTestOptions;
function isTestFunction(value) {
return typeof value === 'function';
}
exports.isTestFunction = isTestFunction;
exports.SKIP = {};
});
//# sourceMappingURL=Test.js.map