UNPKG

11.5 kBJavaScriptView Raw
1(function (factory) {
2 if (typeof module === "object" && typeof module.exports === "object") {
3 var v = factory(require, exports);
4 if (v !== undefined) module.exports = v;
5 }
6 else if (typeof define === "function" && define.amd) {
7 define(["require", "exports", "@theintern/common", "./Deferred"], factory);
8 }
9})(function (require, exports) {
10 "use strict";
11 Object.defineProperty(exports, "__esModule", { value: true });
12 var common_1 = require("@theintern/common");
13 var Deferred_1 = require("./Deferred");
14 var Test = (function () {
15 function Test(options) {
16 var _this = this;
17 this._hasPassed = false;
18 this._isAsync = false;
19 this._usesRemote = false;
20 if (!options.name || !options.test) {
21 throw new Error('A Test requires a name and a test function');
22 }
23 ['timeElapsed', 'hasPassed'].forEach(function (property) {
24 var name = property;
25 if (options[name] != null) {
26 _this["_" + name] = options[name];
27 }
28 delete options[name];
29 });
30 Object.assign(this, options);
31 }
32 Object.defineProperty(Test.prototype, "executor", {
33 get: function () {
34 return this.parent && this.parent.executor;
35 },
36 enumerable: true,
37 configurable: true
38 });
39 Object.defineProperty(Test.prototype, "hasPassed", {
40 get: function () {
41 return this._hasPassed;
42 },
43 enumerable: true,
44 configurable: true
45 });
46 Object.defineProperty(Test.prototype, "id", {
47 get: function () {
48 var name = [];
49 var suiteOrTest = this;
50 do {
51 suiteOrTest.name != null && name.unshift(suiteOrTest.name);
52 } while ((suiteOrTest = suiteOrTest.parent));
53 return name.join(' - ');
54 },
55 enumerable: true,
56 configurable: true
57 });
58 Object.defineProperty(Test.prototype, "isAsync", {
59 get: function () {
60 return this._isAsync;
61 },
62 enumerable: true,
63 configurable: true
64 });
65 Object.defineProperty(Test.prototype, "parentId", {
66 get: function () {
67 return this.parent.id;
68 },
69 enumerable: true,
70 configurable: true
71 });
72 Object.defineProperty(Test.prototype, "remote", {
73 get: function () {
74 this._usesRemote = true;
75 return this.parent.remote;
76 },
77 enumerable: true,
78 configurable: true
79 });
80 Object.defineProperty(Test.prototype, "sessionId", {
81 get: function () {
82 return this.parent.sessionId;
83 },
84 enumerable: true,
85 configurable: true
86 });
87 Object.defineProperty(Test.prototype, "timeElapsed", {
88 get: function () {
89 return this._timeElapsed;
90 },
91 enumerable: true,
92 configurable: true
93 });
94 Object.defineProperty(Test.prototype, "timeout", {
95 get: function () {
96 if (this._timeout != null) {
97 return this._timeout;
98 }
99 if (this.parent && this.parent.timeout != null) {
100 return this.parent.timeout;
101 }
102 return 30000;
103 },
104 set: function (value) {
105 this._timeout = value;
106 },
107 enumerable: true,
108 configurable: true
109 });
110 Test.prototype.async = function (timeout, numCallsUntilResolution) {
111 this._isAsync = true;
112 if (timeout != null) {
113 this.timeout = timeout;
114 }
115 var remainingCalls = numCallsUntilResolution || 1;
116 var dfd = new Deferred_1.default();
117 var oldResolve = dfd.resolve;
118 dfd.resolve = function (value) {
119 --remainingCalls;
120 if (remainingCalls === 0) {
121 oldResolve.call(this, value);
122 }
123 else if (remainingCalls < 0) {
124 throw new Error('resolve called too many times');
125 }
126 };
127 this.async = function () {
128 return dfd;
129 };
130 return dfd;
131 };
132 Test.prototype.restartTimeout = function (timeout) {
133 var _this = this;
134 if (timeout != null) {
135 this.timeout = timeout;
136 }
137 if (this._runTask) {
138 if (this._timer) {
139 clearTimeout(this._timer);
140 }
141 this._timer = setTimeout(function () {
142 _this._timer = undefined;
143 if (_this._runTask) {
144 var error = new Error("Timeout reached on " + _this.id + "#");
145 error.name = 'TimeoutError';
146 _this.error = error;
147 _this._runTask.cancel();
148 }
149 }, this.timeout);
150 }
151 };
152 Test.prototype.run = function () {
153 var _this = this;
154 var startTime;
155 if (this._runTask) {
156 this._runTask.cancel();
157 this._runTask = undefined;
158 }
159 if (this._timer) {
160 clearTimeout(this._timer);
161 this._timer = undefined;
162 }
163 this._usesRemote = false;
164 this._hasPassed = false;
165 this._isAsync = false;
166 this._timeElapsed = 0;
167 this._runTask = undefined;
168 this.async = Object.getPrototypeOf(this).async;
169 this.error = undefined;
170 this.skipped = undefined;
171 return this.executor
172 .emit('testStart', this)
173 .then(function () {
174 startTime = Date.now();
175 })
176 .then(function () {
177 var result = _this.test(_this);
178 if (_this.isAsync) {
179 if (!common_1.isPromiseLike(result)) {
180 result = _this.async().promise;
181 }
182 else {
183 result = common_1.Task.race([_this.async().promise, result]);
184 }
185 }
186 if (common_1.isPromiseLike(result)) {
187 _this._isAsync = true;
188 return new common_1.Task(function (resolve, reject) {
189 _this._runTask = new common_1.Task(function (resolve, reject) {
190 var settled = false;
191 if (common_1.isPromiseLike(result)) {
192 result.then(function () {
193 settled = true;
194 resolve();
195 }, function (error) {
196 settled = true;
197 reject(error);
198 });
199 }
200 if (common_1.isTask(result)) {
201 result
202 .finally(function () {
203 if (!settled) {
204 _this.skipped = 'Canceled';
205 reject(exports.SKIP);
206 }
207 })
208 .catch(function (_error) { });
209 }
210 }, function () {
211 if (common_1.isTask(result)) {
212 result.cancel();
213 }
214 if (_this.error) {
215 reject(_this.error);
216 }
217 }).then(function () {
218 resolve();
219 }, reject);
220 _this.restartTimeout();
221 });
222 }
223 })
224 .finally(function () {
225 if (_this._runTask) {
226 _this._runTask.cancel();
227 }
228 _this._runTask = undefined;
229 _this._timeElapsed = Date.now() - startTime;
230 if (_this._timer) {
231 clearTimeout(_this._timer);
232 _this._timer = undefined;
233 }
234 })
235 .then(function () {
236 if (_this._usesRemote && !_this.isAsync) {
237 throw new Error('Remote used in synchronous test! Tests using this.remote must ' +
238 'return a promise or resolve a this.async deferred.');
239 }
240 _this._hasPassed = true;
241 })
242 .catch(function (error) {
243 if (error !== exports.SKIP) {
244 _this.error = error;
245 throw error;
246 }
247 })
248 .finally(function () { return _this.executor.emit('testEnd', _this); });
249 };
250 Test.prototype.skip = function (message) {
251 if (message === void 0) { message = 'skipped'; }
252 this.skipped = message;
253 throw exports.SKIP;
254 };
255 Test.prototype.toJSON = function () {
256 var _this = this;
257 var json = {};
258 var properties = [
259 'id',
260 'parentId',
261 'name',
262 'sessionId',
263 'timeElapsed',
264 'timeout',
265 'hasPassed',
266 'skipped'
267 ];
268 properties.forEach(function (key) {
269 var value = _this[key];
270 if (typeof value !== 'undefined') {
271 json[key] = value;
272 }
273 });
274 if (this.error) {
275 json.error = {
276 name: this.error.name,
277 message: this.error.message,
278 stack: this.error.stack,
279 showDiff: Boolean(this.error.showDiff)
280 };
281 if (this.error.showDiff) {
282 json.error.actual = this.error.actual;
283 json.error.expected = this.error.expected;
284 }
285 }
286 return json;
287 };
288 return Test;
289 }());
290 exports.default = Test;
291 function isTest(value) {
292 return (value != null &&
293 typeof value.test === 'function' &&
294 typeof value.hasPassed === 'boolean');
295 }
296 exports.isTest = isTest;
297 function isTestOptions(value) {
298 return (value != null &&
299 !(value instanceof Test) &&
300 value.name != null &&
301 value.test != null);
302 }
303 exports.isTestOptions = isTestOptions;
304 function isTestFunction(value) {
305 return typeof value === 'function';
306 }
307 exports.isTestFunction = isTestFunction;
308 exports.SKIP = {};
309});
310//# sourceMappingURL=Test.js.map
\No newline at end of file