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 |
|
\ | No newline at end of file |