selenium-webdriver 3.0.0-beta-1 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.md +109 -0
- package/LICENSE +1 -1
- package/README.md +7 -6
- package/chrome.js +31 -128
- package/edge.js +13 -91
- package/example/chrome_android.js +18 -13
- package/example/chrome_mobile_emulation.js +19 -15
- package/example/google_search.js +11 -11
- package/example/google_search_generator.js +23 -18
- package/example/google_search_test.js +31 -17
- package/example/logging.js +9 -17
- package/example/parallel_flows.js +3 -0
- package/firefox/binary.js +17 -0
- package/firefox/index.js +198 -101
- package/firefox/profile.js +24 -3
- package/http/util.js +95 -59
- package/ie.js +6 -10
- package/index.js +636 -2
- package/lib/actions.js +18 -10
- package/lib/atoms/getAttribute.js +11 -0
- package/lib/atoms/isDisplayed.js +106 -0
- package/lib/firefox/amd64/libnoblur64.so +0 -0
- package/lib/firefox/i386/libnoblur.so +0 -0
- package/lib/firefox/webdriver.xpi +0 -0
- package/lib/http.js +159 -46
- package/lib/logging.js +7 -1
- package/lib/promise.js +602 -358
- package/lib/proxy.js +28 -0
- package/lib/session.js +1 -1
- package/lib/test/build.js +26 -28
- package/lib/test/data/formPage.html +1 -0
- package/lib/test/fileserver.js +12 -10
- package/lib/test/httpserver.js +4 -6
- package/lib/test/index.js +18 -11
- package/lib/test/promise.js +79 -0
- package/lib/webdriver.js +587 -479
- package/opera.js +12 -88
- package/package.json +13 -14
- package/phantomjs.js +7 -14
- package/remote/index.js +201 -30
- package/safari.js +62 -416
- package/test/actions_test.js +9 -11
- package/test/chrome/options_test.js +8 -8
- package/test/chrome/service_test.js +2 -2
- package/test/cookie_test.js +57 -57
- package/test/element_finding_test.js +201 -185
- package/test/execute_script_test.js +108 -111
- package/test/fingerprint_test.js +16 -11
- package/test/firefox/firefox_test.js +75 -49
- package/test/firefox/profile_test.js +1 -3
- package/test/http/util_test.js +21 -27
- package/test/io_test.js +2 -5
- package/test/lib/http_test.js +8 -6
- package/test/lib/promise_aplus_test.js +48 -44
- package/test/lib/promise_error_test.js +687 -611
- package/test/lib/promise_flow_test.js +1810 -1806
- package/test/lib/promise_generator_test.js +227 -225
- package/test/lib/promise_test.js +864 -835
- package/test/lib/until_test.js +1 -1
- package/test/lib/webdriver_test.js +520 -424
- package/test/logging_test.js +43 -45
- package/test/net/portprober_test.js +23 -24
- package/test/page_loading_test.js +84 -78
- package/test/phantomjs/execute_phantomjs_test.js +11 -25
- package/test/proxy_test.js +23 -23
- package/test/remote_test.js +22 -22
- package/test/safari_test.js +108 -0
- package/test/session_test.js +11 -10
- package/test/stale_element_test.js +18 -16
- package/test/tag_name_test.js +7 -5
- package/test/testing/assert_test.js +2 -3
- package/test/testing/index_test.js +163 -117
- package/test/upload_test.js +13 -13
- package/test/window_test.js +94 -70
- package/testing/index.js +176 -37
- package/builder.js +0 -553
- package/lib/safari/client.js +0 -56
|
@@ -22,7 +22,9 @@ const fail = assert.fail;
|
|
|
22
22
|
const sinon = require('sinon');
|
|
23
23
|
|
|
24
24
|
const testutil = require('./testutil');
|
|
25
|
+
const {TimeoutError} = require('../../lib/error');
|
|
25
26
|
const promise = require('../../lib/promise');
|
|
27
|
+
const {enablePromiseManager} = require('../../lib/test/promise');
|
|
26
28
|
|
|
27
29
|
const NativePromise = Promise;
|
|
28
30
|
|
|
@@ -33,2252 +35,2254 @@ const callbackPair = testutil.callbackPair;
|
|
|
33
35
|
const throwStubError = testutil.throwStubError;
|
|
34
36
|
|
|
35
37
|
describe('promise control flow', function() {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
beforeEach(function setUp() {
|
|
39
|
-
promise.LONG_STACK_TRACES = false;
|
|
40
|
-
flow = new promise.ControlFlow();
|
|
41
|
-
promise.setDefaultFlow(flow);
|
|
42
|
-
messages = [];
|
|
43
|
-
flowHistory = [];
|
|
44
|
-
|
|
45
|
-
uncaughtExceptions = [];
|
|
46
|
-
flow.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
|
|
47
|
-
onUncaughtException);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
afterEach(function tearDown() {
|
|
51
|
-
flow.removeAllListeners(
|
|
52
|
-
promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
|
|
53
|
-
assert.deepEqual([], uncaughtExceptions,
|
|
54
|
-
'There were uncaught exceptions');
|
|
55
|
-
flow.reset();
|
|
56
|
-
promise.LONG_STACK_TRACES = false;
|
|
57
|
-
});
|
|
38
|
+
enablePromiseManager(() => {
|
|
39
|
+
let flow, flowHistory, messages, uncaughtExceptions;
|
|
58
40
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
theFlow.removeAllListeners(
|
|
66
|
-
promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
|
|
67
|
-
return new NativePromise(function(fulfill, reject) {
|
|
68
|
-
theFlow.once(promise.ControlFlow.EventType.IDLE, function() {
|
|
69
|
-
reject(Error('expected flow to report an unhandled error'));
|
|
70
|
-
});
|
|
71
|
-
theFlow.once(
|
|
72
|
-
promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
|
|
73
|
-
fulfill);
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function waitForIdle(opt_flow) {
|
|
78
|
-
var theFlow = opt_flow || flow;
|
|
79
|
-
return new NativePromise(function(fulfill, reject) {
|
|
80
|
-
theFlow.once(promise.ControlFlow.EventType.IDLE, fulfill);
|
|
81
|
-
theFlow.once(
|
|
82
|
-
promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, reject);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
41
|
+
beforeEach(function setUp() {
|
|
42
|
+
promise.LONG_STACK_TRACES = false;
|
|
43
|
+
flow = new promise.ControlFlow();
|
|
44
|
+
promise.setDefaultFlow(flow);
|
|
45
|
+
messages = [];
|
|
46
|
+
flowHistory = [];
|
|
85
47
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
48
|
+
uncaughtExceptions = [];
|
|
49
|
+
flow.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
|
|
50
|
+
onUncaughtException);
|
|
89
51
|
});
|
|
90
|
-
}
|
|
91
52
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* @param {string} value The value to push.
|
|
101
|
-
* @param {promise.Promise=} opt_taskPromise Promise to return from
|
|
102
|
-
* the task.
|
|
103
|
-
* @return {!promise.Promise} The result.
|
|
104
|
-
*/
|
|
105
|
-
function schedulePush(value, opt_taskPromise) {
|
|
106
|
-
return scheduleAction(value, function() {
|
|
107
|
-
messages.push(value);
|
|
108
|
-
return opt_taskPromise;
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* @param {string} msg Debug message.
|
|
114
|
-
* @param {!Function} actionFn The function.
|
|
115
|
-
* @return {!promise.Promise} The function result.
|
|
116
|
-
*/
|
|
117
|
-
function scheduleAction(msg, actionFn) {
|
|
118
|
-
return promise.controlFlow().execute(function() {
|
|
119
|
-
flowHistory.push(msg);
|
|
120
|
-
return actionFn();
|
|
121
|
-
}, msg);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* @param {!Function} condition The condition function.
|
|
126
|
-
* @param {number=} opt_timeout The timeout.
|
|
127
|
-
* @param {string=} opt_message Optional message.
|
|
128
|
-
* @return {!promise.Promise} The wait result.
|
|
129
|
-
*/
|
|
130
|
-
function scheduleWait(condition, opt_timeout, opt_message) {
|
|
131
|
-
var msg = opt_message || '';
|
|
132
|
-
// It's not possible to hook into when the wait itself is scheduled, so
|
|
133
|
-
// we record each iteration of the wait loop.
|
|
134
|
-
var count = 0;
|
|
135
|
-
return promise.controlFlow().wait(function() {
|
|
136
|
-
flowHistory.push((count++) + ': ' + msg);
|
|
137
|
-
return condition();
|
|
138
|
-
}, opt_timeout, msg);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function asyncRun(fn, opt_self) {
|
|
142
|
-
NativePromise.resolve().then(() => fn.call(opt_self));
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function assertFlowHistory(var_args) {
|
|
146
|
-
var expected = Array.prototype.slice.call(arguments, 0);
|
|
147
|
-
assert.deepEqual(expected, flowHistory);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function assertMessages(var_args) {
|
|
151
|
-
var expected = Array.prototype.slice.call(arguments, 0);
|
|
152
|
-
assert.deepEqual(expected, messages);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function assertingMessages(var_args) {
|
|
156
|
-
var args = Array.prototype.slice.call(arguments, 0);
|
|
157
|
-
return () => assertMessages.apply(null, args);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function assertFlowIs(flow) {
|
|
161
|
-
assert.equal(flow, promise.controlFlow());
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
describe('testScheduling', function() {
|
|
165
|
-
it('aSimpleFunction', function() {
|
|
166
|
-
schedule('go');
|
|
167
|
-
return waitForIdle().then(function() {
|
|
168
|
-
assertFlowHistory('go');
|
|
169
|
-
});
|
|
53
|
+
afterEach(function tearDown() {
|
|
54
|
+
flow.removeAllListeners(
|
|
55
|
+
promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
|
|
56
|
+
assert.deepEqual([], uncaughtExceptions,
|
|
57
|
+
'There were uncaught exceptions');
|
|
58
|
+
flow.reset();
|
|
59
|
+
promise.LONG_STACK_TRACES = false;
|
|
170
60
|
});
|
|
171
61
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
});
|
|
176
|
-
return waitForIdle().then(function() {
|
|
177
|
-
assertFlowHistory('go');
|
|
178
|
-
});
|
|
179
|
-
});
|
|
62
|
+
function onUncaughtException(e) {
|
|
63
|
+
uncaughtExceptions.push(e);
|
|
64
|
+
}
|
|
180
65
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
return waitForIdle().then(function() {
|
|
186
|
-
assertFlowHistory('a', 'b', 'c');
|
|
66
|
+
function defer() {
|
|
67
|
+
let d = {};
|
|
68
|
+
let promise = new Promise((resolve, reject) => {
|
|
69
|
+
Object.assign(d, {resolve, reject});
|
|
187
70
|
});
|
|
188
|
-
|
|
71
|
+
d.promise = promise;
|
|
72
|
+
return d;
|
|
73
|
+
}
|
|
189
74
|
|
|
190
|
-
|
|
191
|
-
var
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}).
|
|
202
|
-
then(function() {
|
|
203
|
-
assertFlowHistory('a');
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
it('blocksUntilPromiseReturnedByTaskIsResolved', function() {
|
|
208
|
-
var done = promise.defer();
|
|
209
|
-
schedulePush('a', done.promise);
|
|
210
|
-
schedulePush('b');
|
|
211
|
-
setTimeout(function() {
|
|
212
|
-
done.fulfill();
|
|
213
|
-
messages.push('c');
|
|
214
|
-
}, 25);
|
|
215
|
-
return waitForIdle().then(assertingMessages('a', 'c', 'b'));
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
it('waitsForReturnedPromisesToResolve', function() {
|
|
219
|
-
var d1 = new promise.Deferred();
|
|
220
|
-
var d2 = new promise.Deferred();
|
|
221
|
-
|
|
222
|
-
var callback = sinon.spy();
|
|
223
|
-
schedule('a', d1.promise).then(callback);
|
|
224
|
-
|
|
225
|
-
return timeout(5).then(function() {
|
|
226
|
-
assert(!callback.called);
|
|
227
|
-
d1.fulfill(d2.promise);
|
|
228
|
-
return timeout(5);
|
|
229
|
-
}).then(function() {
|
|
230
|
-
assert(!callback.called);
|
|
231
|
-
d2.fulfill('fluffy bunny');
|
|
232
|
-
return waitForIdle();
|
|
233
|
-
}).then(function() {
|
|
234
|
-
assert(callback.called);
|
|
235
|
-
assert.equal('fluffy bunny', callback.getCall(0).args[0]);
|
|
236
|
-
assertFlowHistory('a');
|
|
75
|
+
function waitForAbort(opt_flow) {
|
|
76
|
+
var theFlow = opt_flow || flow;
|
|
77
|
+
theFlow.removeAllListeners(
|
|
78
|
+
promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
|
|
79
|
+
return new NativePromise(function(fulfill, reject) {
|
|
80
|
+
theFlow.once(promise.ControlFlow.EventType.IDLE, function() {
|
|
81
|
+
reject(Error('expected flow to report an unhandled error'));
|
|
82
|
+
});
|
|
83
|
+
theFlow.once(
|
|
84
|
+
promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
|
|
85
|
+
fulfill);
|
|
237
86
|
});
|
|
238
|
-
}
|
|
87
|
+
}
|
|
239
88
|
|
|
240
|
-
|
|
89
|
+
function waitForIdle(opt_flow) {
|
|
90
|
+
var theFlow = opt_flow || flow;
|
|
91
|
+
return new NativePromise(function(fulfill, reject) {
|
|
92
|
+
theFlow.once(promise.ControlFlow.EventType.IDLE, fulfill);
|
|
93
|
+
theFlow.once(
|
|
94
|
+
promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, reject);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function timeout(ms) {
|
|
99
|
+
return new NativePromise(function(fulfill) {
|
|
100
|
+
setTimeout(fulfill, ms);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
function schedule(msg, opt_return) {
|
|
106
|
+
return scheduleAction(msg, function() {
|
|
107
|
+
return opt_return;
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @param {string} value The value to push.
|
|
113
|
+
* @param {promise.Promise=} opt_taskPromise Promise to return from
|
|
114
|
+
* the task.
|
|
115
|
+
* @return {!promise.Promise} The result.
|
|
116
|
+
*/
|
|
117
|
+
function schedulePush(value, opt_taskPromise) {
|
|
118
|
+
return scheduleAction(value, function() {
|
|
119
|
+
messages.push(value);
|
|
120
|
+
return opt_taskPromise;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @param {string} msg Debug message.
|
|
126
|
+
* @param {!Function} actionFn The function.
|
|
127
|
+
* @return {!promise.Promise} The function result.
|
|
128
|
+
*/
|
|
129
|
+
function scheduleAction(msg, actionFn) {
|
|
130
|
+
return promise.controlFlow().execute(function() {
|
|
131
|
+
flowHistory.push(msg);
|
|
132
|
+
return actionFn();
|
|
133
|
+
}, msg);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @param {!Function} condition The condition function.
|
|
138
|
+
* @param {number=} opt_timeout The timeout.
|
|
139
|
+
* @param {string=} opt_message Optional message.
|
|
140
|
+
* @return {!promise.Promise} The wait result.
|
|
141
|
+
*/
|
|
142
|
+
function scheduleWait(condition, opt_timeout, opt_message) {
|
|
143
|
+
var msg = opt_message || '';
|
|
144
|
+
// It's not possible to hook into when the wait itself is scheduled, so
|
|
145
|
+
// we record each iteration of the wait loop.
|
|
241
146
|
var count = 0;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
147
|
+
return promise.controlFlow().wait(function() {
|
|
148
|
+
flowHistory.push((count++) + ': ' + msg);
|
|
149
|
+
return condition();
|
|
150
|
+
}, opt_timeout, msg);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function asyncRun(fn, opt_self) {
|
|
154
|
+
NativePromise.resolve().then(() => fn.call(opt_self));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function assertFlowHistory(var_args) {
|
|
158
|
+
var expected = Array.prototype.slice.call(arguments, 0);
|
|
159
|
+
assert.deepEqual(expected, flowHistory);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function assertMessages(var_args) {
|
|
163
|
+
var expected = Array.prototype.slice.call(arguments, 0);
|
|
164
|
+
assert.deepEqual(expected, messages);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function assertingMessages(var_args) {
|
|
168
|
+
var args = Array.prototype.slice.call(arguments, 0);
|
|
169
|
+
return () => assertMessages.apply(null, args);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function assertFlowIs(flow) {
|
|
173
|
+
assert.equal(flow, promise.controlFlow());
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
describe('testScheduling', function() {
|
|
177
|
+
it('aSimpleFunction', function() {
|
|
178
|
+
schedule('go');
|
|
179
|
+
return waitForIdle().then(function() {
|
|
180
|
+
assertFlowHistory('go');
|
|
181
|
+
});
|
|
248
182
|
});
|
|
249
|
-
});
|
|
250
183
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
order.push(order.length / 2);
|
|
255
|
-
asyncRun(function() {
|
|
256
|
-
order.push('-');
|
|
184
|
+
it('aSimpleFunctionWithANonPromiseReturnValue', function() {
|
|
185
|
+
schedule('go', 123).then(function(value) {
|
|
186
|
+
assert.equal(123, value);
|
|
257
187
|
});
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
return waitForIdle().then(function() {
|
|
263
|
-
assert.deepEqual([0, '-', 1, '-'], order);
|
|
264
|
-
})
|
|
265
|
-
});
|
|
188
|
+
return waitForIdle().then(function() {
|
|
189
|
+
assertFlowHistory('go');
|
|
190
|
+
});
|
|
191
|
+
});
|
|
266
192
|
|
|
267
|
-
|
|
268
|
-
promise.fulfilled().then(function() {
|
|
193
|
+
it('aSimpleSequence', function() {
|
|
269
194
|
schedule('a');
|
|
270
195
|
schedule('b');
|
|
271
196
|
schedule('c');
|
|
272
|
-
|
|
273
|
-
|
|
197
|
+
return waitForIdle().then(function() {
|
|
198
|
+
assertFlowHistory('a', 'b', 'c');
|
|
199
|
+
});
|
|
274
200
|
});
|
|
275
|
-
return waitForIdle();
|
|
276
|
-
});
|
|
277
201
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
var
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
return
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
202
|
+
it('invokesCallbacksWhenTaskIsDone', function() {
|
|
203
|
+
var d = new promise.Deferred();
|
|
204
|
+
var called = false;
|
|
205
|
+
var done = schedule('a', d.promise).then(function(value) {
|
|
206
|
+
called = true;
|
|
207
|
+
assert.equal(123, value);
|
|
208
|
+
});
|
|
209
|
+
return timeout(5).then(function() {
|
|
210
|
+
assert.ok(!called);
|
|
211
|
+
d.fulfill(123);
|
|
212
|
+
return done;
|
|
213
|
+
}).
|
|
214
|
+
then(function() {
|
|
215
|
+
assertFlowHistory('a');
|
|
216
|
+
});
|
|
290
217
|
});
|
|
291
|
-
});
|
|
292
218
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
219
|
+
it('blocksUntilPromiseReturnedByTaskIsResolved', function() {
|
|
220
|
+
var done = promise.defer();
|
|
221
|
+
schedulePush('a', done.promise);
|
|
222
|
+
schedulePush('b');
|
|
296
223
|
setTimeout(function() {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
},
|
|
300
|
-
return
|
|
301
|
-
});
|
|
302
|
-
schedule('b');
|
|
303
|
-
return waitForIdle().then(function() {
|
|
304
|
-
assertFlowHistory('a', 'c', 'b');
|
|
224
|
+
done.fulfill();
|
|
225
|
+
messages.push('c');
|
|
226
|
+
}, 25);
|
|
227
|
+
return waitForIdle().then(assertingMessages('a', 'c', 'b'));
|
|
305
228
|
});
|
|
306
|
-
});
|
|
307
|
-
});
|
|
308
229
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
230
|
+
it('waitsForReturnedPromisesToResolve', function() {
|
|
231
|
+
var d1 = new promise.Deferred();
|
|
232
|
+
var d2 = new promise.Deferred();
|
|
233
|
+
|
|
234
|
+
var callback = sinon.spy();
|
|
235
|
+
schedule('a', d1.promise).then(callback);
|
|
236
|
+
|
|
237
|
+
return timeout(5).then(function() {
|
|
238
|
+
assert(!callback.called);
|
|
239
|
+
d1.fulfill(d2.promise);
|
|
240
|
+
return timeout(5);
|
|
241
|
+
}).then(function() {
|
|
242
|
+
assert(!callback.called);
|
|
243
|
+
d2.fulfill('fluffy bunny');
|
|
244
|
+
return waitForIdle();
|
|
245
|
+
}).then(function() {
|
|
246
|
+
assert(callback.called);
|
|
247
|
+
assert.equal('fluffy bunny', callback.getCall(0).args[0]);
|
|
248
|
+
assertFlowHistory('a');
|
|
249
|
+
});
|
|
313
250
|
});
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
251
|
+
|
|
252
|
+
it('executesTasksInAFutureTurnAfterTheyAreScheduled', function() {
|
|
253
|
+
var count = 0;
|
|
254
|
+
function incr() { count++; }
|
|
255
|
+
|
|
256
|
+
scheduleAction('', incr);
|
|
257
|
+
assert.equal(0, count);
|
|
258
|
+
return waitForIdle().then(function() {
|
|
259
|
+
assert.equal(1, count);
|
|
260
|
+
});
|
|
317
261
|
});
|
|
318
|
-
});
|
|
319
262
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
263
|
+
it('executesOneTaskPerTurnOfTheEventLoop', function() {
|
|
264
|
+
var order = [];
|
|
265
|
+
function go() {
|
|
266
|
+
order.push(order.length / 2);
|
|
267
|
+
asyncRun(function() {
|
|
268
|
+
order.push('-');
|
|
325
269
|
});
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
scheduleAction('', go);
|
|
273
|
+
scheduleAction('', go);
|
|
274
|
+
return waitForIdle().then(function() {
|
|
275
|
+
assert.deepEqual([0, '-', 1, '-'], order);
|
|
276
|
+
})
|
|
329
277
|
});
|
|
330
|
-
schedule('b');
|
|
331
278
|
|
|
332
|
-
|
|
333
|
-
|
|
279
|
+
it('firstScheduledTaskIsWithinACallback', function() {
|
|
280
|
+
promise.fulfilled().then(function() {
|
|
281
|
+
schedule('a');
|
|
282
|
+
schedule('b');
|
|
283
|
+
schedule('c');
|
|
284
|
+
}).then(function() {
|
|
285
|
+
assertFlowHistory('a', 'b', 'c');
|
|
286
|
+
});
|
|
287
|
+
return waitForIdle();
|
|
334
288
|
});
|
|
335
|
-
});
|
|
336
289
|
|
|
337
|
-
|
|
338
|
-
|
|
290
|
+
it('newTasksAddedWhileWaitingOnTaskReturnedPromise1', function() {
|
|
291
|
+
scheduleAction('a', function() {
|
|
292
|
+
var d = promise.defer();
|
|
293
|
+
setTimeout(function() {
|
|
294
|
+
schedule('c');
|
|
295
|
+
d.fulfill();
|
|
296
|
+
}, 10);
|
|
297
|
+
return d.promise;
|
|
298
|
+
});
|
|
339
299
|
schedule('b');
|
|
340
|
-
return
|
|
341
|
-
|
|
300
|
+
return waitForIdle().then(function() {
|
|
301
|
+
assertFlowHistory('a', 'b', 'c');
|
|
342
302
|
});
|
|
343
303
|
});
|
|
344
|
-
schedule('d');
|
|
345
304
|
|
|
346
|
-
|
|
347
|
-
|
|
305
|
+
it('newTasksAddedWhileWaitingOnTaskReturnedPromise2', function() {
|
|
306
|
+
scheduleAction('a', function() {
|
|
307
|
+
var d = promise.defer();
|
|
308
|
+
setTimeout(function() {
|
|
309
|
+
schedule('c');
|
|
310
|
+
asyncRun(d.fulfill);
|
|
311
|
+
}, 10);
|
|
312
|
+
return d.promise;
|
|
313
|
+
});
|
|
314
|
+
schedule('b');
|
|
315
|
+
return waitForIdle().then(function() {
|
|
316
|
+
assertFlowHistory('a', 'c', 'b');
|
|
317
|
+
});
|
|
348
318
|
});
|
|
349
319
|
});
|
|
350
320
|
|
|
351
|
-
|
|
352
|
-
|
|
321
|
+
describe('testFraming', function() {
|
|
322
|
+
it('callbacksRunInANewFrame', function() {
|
|
323
|
+
schedule('a').then(function() {
|
|
324
|
+
schedule('c');
|
|
325
|
+
});
|
|
353
326
|
schedule('b');
|
|
354
|
-
return
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
then(function() { return promise.delayed(5) }).
|
|
358
|
-
then(function() { return schedule('c'); });
|
|
359
|
-
});
|
|
360
|
-
schedule('d');
|
|
361
|
-
|
|
362
|
-
return waitForIdle().then(function() {
|
|
363
|
-
assertFlowHistory('a', 'b', 'c', 'd');
|
|
327
|
+
return waitForIdle().then(function() {
|
|
328
|
+
assertFlowHistory('a', 'c', 'b');
|
|
329
|
+
});
|
|
364
330
|
});
|
|
365
|
-
});
|
|
366
331
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
then(function() {
|
|
370
|
-
schedule('
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
schedule('d');
|
|
332
|
+
it('lotsOfNesting', function() {
|
|
333
|
+
schedule('a').then(function() {
|
|
334
|
+
schedule('c').then(function() {
|
|
335
|
+
schedule('e').then(function() {
|
|
336
|
+
schedule('g');
|
|
337
|
+
});
|
|
338
|
+
schedule('f');
|
|
375
339
|
});
|
|
376
|
-
|
|
340
|
+
schedule('d');
|
|
341
|
+
});
|
|
342
|
+
schedule('b');
|
|
377
343
|
|
|
378
|
-
|
|
379
|
-
|
|
344
|
+
return waitForIdle().then(function() {
|
|
345
|
+
assertFlowHistory('a', 'c', 'e', 'g', 'f', 'd', 'b');
|
|
346
|
+
});
|
|
380
347
|
});
|
|
381
|
-
});
|
|
382
348
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
349
|
+
it('callbackReturnsPromiseThatDependsOnATask_1', function() {
|
|
350
|
+
schedule('a').then(function() {
|
|
351
|
+
schedule('b');
|
|
352
|
+
return promise.delayed(5).then(function() {
|
|
387
353
|
return schedule('c');
|
|
388
|
-
}).
|
|
389
|
-
then(function() {
|
|
390
|
-
schedule('d');
|
|
391
354
|
});
|
|
392
|
-
|
|
355
|
+
});
|
|
356
|
+
schedule('d');
|
|
393
357
|
|
|
394
|
-
|
|
395
|
-
|
|
358
|
+
return waitForIdle().then(function() {
|
|
359
|
+
assertFlowHistory('a', 'b', 'c', 'd');
|
|
360
|
+
});
|
|
396
361
|
});
|
|
397
|
-
});
|
|
398
362
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
363
|
+
it('callbackReturnsPromiseThatDependsOnATask_2', function() {
|
|
364
|
+
schedule('a').then(function() {
|
|
365
|
+
schedule('b');
|
|
366
|
+
return promise.delayed(5).
|
|
367
|
+
then(function() { return promise.delayed(5) }).
|
|
368
|
+
then(function() { return promise.delayed(5) }).
|
|
369
|
+
then(function() { return promise.delayed(5) }).
|
|
370
|
+
then(function() { return schedule('c'); });
|
|
371
|
+
});
|
|
372
|
+
schedule('d');
|
|
404
373
|
|
|
405
|
-
|
|
406
|
-
|
|
374
|
+
return waitForIdle().then(function() {
|
|
375
|
+
assertFlowHistory('a', 'b', 'c', 'd');
|
|
376
|
+
});
|
|
407
377
|
});
|
|
408
|
-
});
|
|
409
378
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
379
|
+
it('eachCallbackWaitsForAllScheduledTasksToComplete', function() {
|
|
380
|
+
schedule('a').
|
|
381
|
+
then(function() {
|
|
382
|
+
schedule('b');
|
|
383
|
+
schedule('c');
|
|
384
|
+
}).
|
|
385
|
+
then(function() {
|
|
386
|
+
schedule('d');
|
|
387
|
+
});
|
|
388
|
+
schedule('e');
|
|
415
389
|
|
|
416
|
-
|
|
417
|
-
|
|
390
|
+
return waitForIdle().then(function() {
|
|
391
|
+
assertFlowHistory('a', 'b', 'c', 'd', 'e');
|
|
392
|
+
});
|
|
418
393
|
});
|
|
419
|
-
});
|
|
420
394
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
395
|
+
it('eachCallbackWaitsForReturnTasksToComplete', function() {
|
|
396
|
+
schedule('a').
|
|
397
|
+
then(function() {
|
|
398
|
+
schedule('b');
|
|
399
|
+
return schedule('c');
|
|
400
|
+
}).
|
|
401
|
+
then(function() {
|
|
402
|
+
schedule('d');
|
|
403
|
+
});
|
|
404
|
+
schedule('e');
|
|
427
405
|
|
|
428
|
-
|
|
429
|
-
|
|
406
|
+
return waitForIdle().then(function() {
|
|
407
|
+
assertFlowHistory('a', 'b', 'c', 'd', 'e');
|
|
408
|
+
});
|
|
430
409
|
});
|
|
431
|
-
});
|
|
432
410
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
411
|
+
it('callbacksOnAResolvedPromiseInsertIntoTheCurrentFlow', function() {
|
|
412
|
+
promise.fulfilled().then(function() {
|
|
413
|
+
schedule('b');
|
|
414
|
+
});
|
|
415
|
+
schedule('a');
|
|
438
416
|
|
|
439
|
-
|
|
440
|
-
|
|
417
|
+
return waitForIdle().then(function() {
|
|
418
|
+
assertFlowHistory('b', 'a');
|
|
419
|
+
});
|
|
441
420
|
});
|
|
442
|
-
});
|
|
443
421
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
schedule('b').then(function() {
|
|
447
|
-
a.then(function() {
|
|
422
|
+
it('callbacksInterruptTheFlowWhenPromiseIsResolved', function() {
|
|
423
|
+
schedule('a').then(function() {
|
|
448
424
|
schedule('c');
|
|
449
|
-
schedule('d');
|
|
450
425
|
});
|
|
451
|
-
|
|
452
|
-
a.then(function() {
|
|
453
|
-
schedule('f');
|
|
454
|
-
e.then(function() {
|
|
455
|
-
schedule('g');
|
|
456
|
-
});
|
|
457
|
-
schedule('h');
|
|
458
|
-
});
|
|
459
|
-
schedule('i');
|
|
460
|
-
});
|
|
461
|
-
schedule('j');
|
|
426
|
+
schedule('b');
|
|
462
427
|
|
|
463
|
-
|
|
464
|
-
|
|
428
|
+
return waitForIdle().then(function() {
|
|
429
|
+
assertFlowHistory('a', 'c', 'b');
|
|
430
|
+
});
|
|
465
431
|
});
|
|
466
|
-
});
|
|
467
|
-
});
|
|
468
432
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
433
|
+
it('allCallbacksInAFrameAreScheduledWhenPromiseIsResolved', function() {
|
|
434
|
+
var a = schedule('a');
|
|
435
|
+
a.then(function() { schedule('b'); });
|
|
436
|
+
schedule('c');
|
|
437
|
+
a.then(function() { schedule('d'); });
|
|
438
|
+
schedule('e');
|
|
475
439
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
return waitForIdle();
|
|
481
|
-
});
|
|
440
|
+
return waitForIdle().then(function() {
|
|
441
|
+
assertFlowHistory('a', 'b', 'c', 'd', 'e');
|
|
442
|
+
});
|
|
443
|
+
});
|
|
482
444
|
|
|
483
|
-
|
|
484
|
-
|
|
445
|
+
it('tasksScheduledInInActiveFrameDoNotGetPrecedence', function() {
|
|
446
|
+
var d = promise.fulfilled();
|
|
447
|
+
schedule('a');
|
|
485
448
|
schedule('b');
|
|
486
|
-
|
|
487
|
-
}).
|
|
488
|
-
then(fail, assertIsStubError);
|
|
489
|
-
return waitForIdle();
|
|
490
|
-
});
|
|
449
|
+
d.then(function() { schedule('c'); });
|
|
491
450
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
451
|
+
return waitForIdle().then(function() {
|
|
452
|
+
assertFlowHistory('a', 'b', 'c');
|
|
453
|
+
});
|
|
495
454
|
});
|
|
496
|
-
return waitForAbort().then(assertIsStubError);
|
|
497
|
-
});
|
|
498
|
-
|
|
499
|
-
it('abortsIfThereIsAnUnhandledRejection', function() {
|
|
500
|
-
promise.rejected(new StubError);
|
|
501
|
-
schedule('this should not run');
|
|
502
|
-
return waitForAbort().
|
|
503
|
-
then(assertIsStubError).
|
|
504
|
-
then(function() {
|
|
505
|
-
assertFlowHistory(/* none */);
|
|
506
|
-
});
|
|
507
|
-
});
|
|
508
455
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
return waitForAbort().
|
|
516
|
-
then(assertIsStubError).
|
|
517
|
-
then(function() {
|
|
518
|
-
assertFlowHistory('a', 'b', 'c');
|
|
456
|
+
it('tasksScheduledInAFrameGetPrecedence_1', function() {
|
|
457
|
+
var a = schedule('a');
|
|
458
|
+
schedule('b').then(function() {
|
|
459
|
+
a.then(function() {
|
|
460
|
+
schedule('c');
|
|
461
|
+
schedule('d');
|
|
519
462
|
});
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
return waitForAbort().
|
|
528
|
-
then(assertIsStubError).
|
|
529
|
-
then(function() {
|
|
530
|
-
assertFlowHistory('outer task', 'inner task');
|
|
463
|
+
var e = schedule('e');
|
|
464
|
+
a.then(function() {
|
|
465
|
+
schedule('f');
|
|
466
|
+
e.then(function() {
|
|
467
|
+
schedule('g');
|
|
468
|
+
});
|
|
469
|
+
schedule('h');
|
|
531
470
|
});
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
it('abortsFromUnhandledFramedTaskFailures_2', function() {
|
|
535
|
-
schedule('a').then(function() {
|
|
536
|
-
schedule('b').then(function() {
|
|
537
|
-
scheduleAction('c', throwStubError);
|
|
538
|
-
// This should not execute.
|
|
539
|
-
schedule('d');
|
|
471
|
+
schedule('i');
|
|
540
472
|
});
|
|
541
|
-
|
|
473
|
+
schedule('j');
|
|
542
474
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
assertFlowHistory('a', 'b', 'c');
|
|
547
|
-
});
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
it('abortsWhenErrorBubblesUpFromFullyResolvingAnObject', function() {
|
|
551
|
-
var callback = sinon.spy();
|
|
552
|
-
|
|
553
|
-
scheduleAction('', function() {
|
|
554
|
-
var obj = {'foo': promise.rejected(new StubError)};
|
|
555
|
-
return promise.fullyResolved(obj).then(callback);
|
|
475
|
+
return waitForIdle().then(function() {
|
|
476
|
+
assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j');
|
|
477
|
+
});
|
|
556
478
|
});
|
|
557
|
-
|
|
558
|
-
return waitForAbort().
|
|
559
|
-
then(assertIsStubError).
|
|
560
|
-
then(() => assert(!callback.called));
|
|
561
|
-
});
|
|
562
|
-
|
|
563
|
-
it('abortsWhenErrorBubblesUpFromFullyResolvingAnObject_withCallback', function() {
|
|
564
|
-
var callback1 = sinon.spy();
|
|
565
|
-
var callback2 = sinon.spy();
|
|
566
|
-
|
|
567
|
-
scheduleAction('', function() {
|
|
568
|
-
var obj = {'foo': promise.rejected(new StubError)};
|
|
569
|
-
return promise.fullyResolved(obj).then(callback1);
|
|
570
|
-
}).then(callback2);
|
|
571
|
-
|
|
572
|
-
return waitForAbort().
|
|
573
|
-
then(assertIsStubError).
|
|
574
|
-
then(() => assert(!callback1.called)).
|
|
575
|
-
then(() => assert(!callback2.called));
|
|
576
479
|
});
|
|
577
480
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
}).
|
|
584
|
-
catch(errback);
|
|
585
|
-
return waitForIdle().then(function() {
|
|
586
|
-
assert(errback.called);
|
|
587
|
-
assertIsStubError(errback.getCall(0).args[0]);
|
|
481
|
+
describe('testErrorHandling', function() {
|
|
482
|
+
it('thrownErrorsArePassedToTaskErrback', function() {
|
|
483
|
+
scheduleAction('function that throws', throwStubError).
|
|
484
|
+
then(fail, assertIsStubError);
|
|
485
|
+
return waitForIdle();
|
|
588
486
|
});
|
|
589
|
-
});
|
|
590
|
-
|
|
591
|
-
it('nestedCommandFailuresCanBeCaughtAndSuppressed', function() {
|
|
592
|
-
var errback = sinon.spy();
|
|
593
|
-
schedule('a').then(function() {
|
|
594
|
-
return schedule('b').then(function() {
|
|
595
|
-
return schedule('c').then(function() {
|
|
596
|
-
throw new StubError;
|
|
597
|
-
});
|
|
598
|
-
});
|
|
599
|
-
}).catch(errback);
|
|
600
|
-
schedule('d');
|
|
601
|
-
return waitForIdle().
|
|
602
|
-
then(function() {
|
|
603
|
-
assert(errback.called);
|
|
604
|
-
assertIsStubError(errback.getCall(0).args[0]);
|
|
605
|
-
assertFlowHistory('a', 'b', 'c', 'd');
|
|
606
|
-
});
|
|
607
|
-
});
|
|
608
487
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
488
|
+
it('thrownErrorsPropagateThroughPromiseChain', function() {
|
|
489
|
+
scheduleAction('function that throws', throwStubError).
|
|
490
|
+
then(fail).
|
|
491
|
+
then(fail, assertIsStubError);
|
|
492
|
+
return waitForIdle();
|
|
613
493
|
});
|
|
614
|
-
schedule('should never run');
|
|
615
494
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
it('aTaskThatReutrnsARejectedPromise', function() {
|
|
624
|
-
schedule('a');
|
|
625
|
-
scheduleAction('sub-tasks', function() {
|
|
626
|
-
return promise.rejected(new StubError);
|
|
495
|
+
it('catchesErrorsFromFailedTasksInAFrame', function() {
|
|
496
|
+
schedule('a').then(function() {
|
|
497
|
+
schedule('b');
|
|
498
|
+
scheduleAction('function that throws', throwStubError);
|
|
499
|
+
}).
|
|
500
|
+
then(fail, assertIsStubError);
|
|
501
|
+
return waitForIdle();
|
|
627
502
|
});
|
|
628
|
-
schedule('should never run');
|
|
629
|
-
|
|
630
|
-
return waitForAbort().
|
|
631
|
-
then(assertIsStubError).
|
|
632
|
-
then(function() {
|
|
633
|
-
assertFlowHistory('a', 'sub-tasks');
|
|
634
|
-
});
|
|
635
|
-
});
|
|
636
|
-
|
|
637
|
-
it('discardsSubtasksIfTaskThrows', function() {
|
|
638
|
-
var pair = callbackPair(null, assertIsStubError);
|
|
639
|
-
scheduleAction('a', function() {
|
|
640
|
-
schedule('b');
|
|
641
|
-
schedule('c');
|
|
642
|
-
throwStubError();
|
|
643
|
-
}).then(pair.callback, pair.errback);
|
|
644
|
-
schedule('d');
|
|
645
|
-
|
|
646
|
-
return waitForIdle().
|
|
647
|
-
then(pair.assertErrback).
|
|
648
|
-
then(function() {
|
|
649
|
-
assertFlowHistory('a', 'd');
|
|
650
|
-
});
|
|
651
|
-
});
|
|
652
|
-
|
|
653
|
-
it('discardsRemainingSubtasksIfASubtaskFails', function() {
|
|
654
|
-
var pair = callbackPair(null, assertIsStubError);
|
|
655
|
-
scheduleAction('a', function() {
|
|
656
|
-
schedule('b');
|
|
657
|
-
scheduleAction('c', throwStubError);
|
|
658
|
-
schedule('d');
|
|
659
|
-
}).then(pair.callback, pair.errback);
|
|
660
|
-
schedule('e');
|
|
661
|
-
|
|
662
|
-
return waitForIdle().
|
|
663
|
-
then(pair.assertErrback).
|
|
664
|
-
then(function() {
|
|
665
|
-
assertFlowHistory('a', 'b', 'c', 'e');
|
|
666
|
-
});
|
|
667
|
-
});
|
|
668
|
-
});
|
|
669
|
-
|
|
670
|
-
describe('testTryModelingFinally', function() {
|
|
671
|
-
it('happyPath', function() {
|
|
672
|
-
/* Model:
|
|
673
|
-
try {
|
|
674
|
-
doFoo();
|
|
675
|
-
doBar();
|
|
676
|
-
} finally {
|
|
677
|
-
doBaz();
|
|
678
|
-
}
|
|
679
|
-
*/
|
|
680
|
-
schedulePush('foo').
|
|
681
|
-
then(() => schedulePush('bar')).
|
|
682
|
-
finally(() => schedulePush('baz'));
|
|
683
|
-
return waitForIdle().then(assertingMessages('foo', 'bar', 'baz'));
|
|
684
|
-
});
|
|
685
|
-
|
|
686
|
-
it('firstTryFails', function() {
|
|
687
|
-
/* Model:
|
|
688
|
-
try {
|
|
689
|
-
doFoo();
|
|
690
|
-
doBar();
|
|
691
|
-
} finally {
|
|
692
|
-
doBaz();
|
|
693
|
-
}
|
|
694
|
-
*/
|
|
695
|
-
|
|
696
|
-
scheduleAction('doFoo and throw', function() {
|
|
697
|
-
messages.push('foo');
|
|
698
|
-
throw new StubError;
|
|
699
|
-
}).
|
|
700
|
-
then(function() { schedulePush('bar'); }).
|
|
701
|
-
finally(function() { schedulePush('baz'); });
|
|
702
503
|
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
it('secondTryFails', function() {
|
|
709
|
-
/* Model:
|
|
710
|
-
try {
|
|
711
|
-
doFoo();
|
|
712
|
-
doBar();
|
|
713
|
-
} finally {
|
|
714
|
-
doBaz();
|
|
715
|
-
}
|
|
716
|
-
*/
|
|
717
|
-
|
|
718
|
-
schedulePush('foo').
|
|
719
|
-
then(function() {
|
|
720
|
-
return scheduleAction('doBar and throw', function() {
|
|
721
|
-
messages.push('bar');
|
|
722
|
-
throw new StubError;
|
|
723
|
-
});
|
|
724
|
-
}).
|
|
725
|
-
finally(function() {
|
|
726
|
-
return schedulePush('baz');
|
|
727
|
-
});
|
|
728
|
-
return waitForAbort().
|
|
729
|
-
then(assertIsStubError).
|
|
730
|
-
then(assertingMessages('foo', 'bar', 'baz'));
|
|
731
|
-
});
|
|
732
|
-
});
|
|
733
|
-
|
|
734
|
-
describe('testTaskCallbacksInterruptFlow', function() {
|
|
735
|
-
it('(base case)', function() {
|
|
736
|
-
schedule('a').then(function() {
|
|
737
|
-
schedule('b');
|
|
738
|
-
});
|
|
739
|
-
schedule('c');
|
|
740
|
-
return waitForIdle().then(function() {
|
|
741
|
-
assertFlowHistory('a', 'b', 'c');
|
|
504
|
+
it('abortsIfOnlyTaskReturnsAnUnhandledRejection', function() {
|
|
505
|
+
scheduleAction('function that returns rejected promise', function() {
|
|
506
|
+
return promise.rejected(new StubError);
|
|
507
|
+
});
|
|
508
|
+
return waitForAbort().then(assertIsStubError);
|
|
742
509
|
});
|
|
743
|
-
});
|
|
744
510
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
assertFlowHistory('a', 'b', 'c');
|
|
511
|
+
it('abortsIfThereIsAnUnhandledRejection', function() {
|
|
512
|
+
promise.rejected(new StubError);
|
|
513
|
+
schedule('this should not run');
|
|
514
|
+
return waitForAbort().
|
|
515
|
+
then(assertIsStubError).
|
|
516
|
+
then(function() {
|
|
517
|
+
assertFlowHistory(/* none */);
|
|
518
|
+
});
|
|
754
519
|
});
|
|
755
|
-
});
|
|
756
520
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
scheduleAction('a', function() {
|
|
760
|
-
return aPromise;
|
|
761
|
-
}).then(function(value) {
|
|
762
|
-
assert.equal(123, value);
|
|
521
|
+
it('abortsSequenceIfATaskFails', function() {
|
|
522
|
+
schedule('a');
|
|
763
523
|
schedule('b');
|
|
524
|
+
scheduleAction('c', throwStubError);
|
|
525
|
+
schedule('d'); // Should never execute.
|
|
526
|
+
|
|
527
|
+
return waitForAbort().
|
|
528
|
+
then(assertIsStubError).
|
|
529
|
+
then(function() {
|
|
530
|
+
assertFlowHistory('a', 'b', 'c');
|
|
531
|
+
});
|
|
764
532
|
});
|
|
765
|
-
schedule('c');
|
|
766
|
-
return waitForIdle().then(function() {
|
|
767
|
-
assertFlowHistory('a', 'b', 'c');
|
|
768
|
-
});
|
|
769
|
-
});
|
|
770
533
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
schedule('
|
|
534
|
+
it('abortsFromUnhandledFramedTaskFailures_1', function() {
|
|
535
|
+
schedule('outer task').then(function() {
|
|
536
|
+
scheduleAction('inner task', throwStubError);
|
|
537
|
+
});
|
|
538
|
+
schedule('this should not run');
|
|
539
|
+
return waitForAbort().
|
|
540
|
+
then(assertIsStubError).
|
|
541
|
+
then(function() {
|
|
542
|
+
assertFlowHistory('outer task', 'inner task');
|
|
543
|
+
});
|
|
776
544
|
});
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
545
|
+
|
|
546
|
+
it('abortsFromUnhandledFramedTaskFailures_2', function() {
|
|
547
|
+
schedule('a').then(function() {
|
|
548
|
+
schedule('b').then(function() {
|
|
549
|
+
scheduleAction('c', throwStubError);
|
|
550
|
+
// This should not execute.
|
|
551
|
+
schedule('d');
|
|
552
|
+
});
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
return waitForAbort().
|
|
556
|
+
then(assertIsStubError).
|
|
557
|
+
then(function() {
|
|
558
|
+
assertFlowHistory('a', 'b', 'c');
|
|
559
|
+
});
|
|
780
560
|
});
|
|
781
|
-
});
|
|
782
561
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
562
|
+
it('abortsWhenErrorBubblesUpFromFullyResolvingAnObject', function() {
|
|
563
|
+
var callback = sinon.spy();
|
|
564
|
+
|
|
565
|
+
scheduleAction('', function() {
|
|
566
|
+
var obj = {'foo': promise.rejected(new StubError)};
|
|
567
|
+
return promise.fullyResolved(obj).then(callback);
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
return waitForAbort().
|
|
571
|
+
then(assertIsStubError).
|
|
572
|
+
then(() => assert(!callback.called));
|
|
790
573
|
});
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
574
|
+
|
|
575
|
+
it('abortsWhenErrorBubblesUpFromFullyResolvingAnObject_withCallback', function() {
|
|
576
|
+
var callback1 = sinon.spy();
|
|
577
|
+
var callback2 = sinon.spy();
|
|
578
|
+
|
|
579
|
+
scheduleAction('', function() {
|
|
580
|
+
var obj = {'foo': promise.rejected(new StubError)};
|
|
581
|
+
return promise.fullyResolved(obj).then(callback1);
|
|
582
|
+
}).then(callback2);
|
|
583
|
+
|
|
584
|
+
return waitForAbort().
|
|
585
|
+
then(assertIsStubError).
|
|
586
|
+
then(() => assert(!callback1.called)).
|
|
587
|
+
then(() => assert(!callback2.called));
|
|
794
588
|
});
|
|
795
|
-
});
|
|
796
589
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
schedule('
|
|
800
|
-
|
|
590
|
+
it('canCatchErrorsFromNestedTasks', function() {
|
|
591
|
+
var errback = sinon.spy();
|
|
592
|
+
schedule('a').
|
|
593
|
+
then(function() {
|
|
594
|
+
return scheduleAction('b', throwStubError);
|
|
595
|
+
}).
|
|
596
|
+
catch(errback);
|
|
597
|
+
return waitForIdle().then(function() {
|
|
598
|
+
assert(errback.called);
|
|
599
|
+
assertIsStubError(errback.getCall(0).args[0]);
|
|
801
600
|
});
|
|
802
601
|
});
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
602
|
+
|
|
603
|
+
it('nestedCommandFailuresCanBeCaughtAndSuppressed', function() {
|
|
604
|
+
var errback = sinon.spy();
|
|
605
|
+
schedule('a').then(function() {
|
|
606
|
+
return schedule('b').then(function() {
|
|
607
|
+
return schedule('c').then(function() {
|
|
608
|
+
throw new StubError;
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
}).catch(errback);
|
|
612
|
+
schedule('d');
|
|
613
|
+
return waitForIdle().
|
|
614
|
+
then(function() {
|
|
615
|
+
assert(errback.called);
|
|
616
|
+
assertIsStubError(errback.getCall(0).args[0]);
|
|
617
|
+
assertFlowHistory('a', 'b', 'c', 'd');
|
|
618
|
+
});
|
|
806
619
|
});
|
|
807
|
-
});
|
|
808
|
-
});
|
|
809
620
|
|
|
810
|
-
|
|
621
|
+
it('aTaskWithAnUnhandledPromiseRejection', function() {
|
|
622
|
+
schedule('a');
|
|
623
|
+
scheduleAction('sub-tasks', function() {
|
|
624
|
+
promise.rejected(new StubError);
|
|
625
|
+
});
|
|
626
|
+
schedule('should never run');
|
|
811
627
|
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
628
|
+
return waitForAbort().
|
|
629
|
+
then(assertIsStubError).
|
|
630
|
+
then(function() {
|
|
631
|
+
assertFlowHistory('a', 'sub-tasks');
|
|
632
|
+
});
|
|
817
633
|
});
|
|
818
|
-
schedule('e');
|
|
819
634
|
|
|
820
|
-
|
|
821
|
-
|
|
635
|
+
it('aTaskThatReutrnsARejectedPromise', function() {
|
|
636
|
+
schedule('a');
|
|
637
|
+
scheduleAction('sub-tasks', function() {
|
|
638
|
+
return promise.rejected(new StubError);
|
|
639
|
+
});
|
|
640
|
+
schedule('should never run');
|
|
641
|
+
|
|
642
|
+
return waitForAbort().
|
|
643
|
+
then(assertIsStubError).
|
|
644
|
+
then(function() {
|
|
645
|
+
assertFlowHistory('a', 'sub-tasks');
|
|
646
|
+
});
|
|
822
647
|
});
|
|
823
|
-
});
|
|
824
648
|
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
649
|
+
it('discardsSubtasksIfTaskThrows', function() {
|
|
650
|
+
var pair = callbackPair(null, assertIsStubError);
|
|
651
|
+
scheduleAction('a', function() {
|
|
652
|
+
schedule('b');
|
|
653
|
+
schedule('c');
|
|
654
|
+
throwStubError();
|
|
655
|
+
}).then(pair.callback, pair.errback);
|
|
829
656
|
schedule('d');
|
|
830
|
-
|
|
657
|
+
|
|
658
|
+
return waitForIdle().
|
|
659
|
+
then(pair.assertErrback).
|
|
660
|
+
then(function() {
|
|
661
|
+
assertFlowHistory('a', 'd');
|
|
662
|
+
});
|
|
831
663
|
});
|
|
832
|
-
schedule('f');
|
|
833
664
|
|
|
834
|
-
|
|
835
|
-
|
|
665
|
+
it('discardsRemainingSubtasksIfASubtaskFails', function() {
|
|
666
|
+
var pair = callbackPair(null, assertIsStubError);
|
|
667
|
+
scheduleAction('a', function() {
|
|
668
|
+
schedule('b');
|
|
669
|
+
scheduleAction('c', throwStubError);
|
|
670
|
+
schedule('d');
|
|
671
|
+
}).then(pair.callback, pair.errback);
|
|
672
|
+
schedule('e');
|
|
673
|
+
|
|
674
|
+
return waitForIdle().
|
|
675
|
+
then(pair.assertErrback).
|
|
676
|
+
then(function() {
|
|
677
|
+
assertFlowHistory('a', 'b', 'c', 'e');
|
|
678
|
+
});
|
|
836
679
|
});
|
|
837
680
|
});
|
|
838
681
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
682
|
+
describe('testTryModelingFinally', function() {
|
|
683
|
+
it('happyPath', function() {
|
|
684
|
+
/* Model:
|
|
685
|
+
try {
|
|
686
|
+
doFoo();
|
|
687
|
+
doBar();
|
|
688
|
+
} finally {
|
|
689
|
+
doBaz();
|
|
690
|
+
}
|
|
691
|
+
*/
|
|
692
|
+
schedulePush('foo').
|
|
693
|
+
then(() => schedulePush('bar')).
|
|
694
|
+
finally(() => schedulePush('baz'));
|
|
695
|
+
return waitForIdle().then(assertingMessages('foo', 'bar', 'baz'));
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
it('firstTryFails', function() {
|
|
699
|
+
/* Model:
|
|
700
|
+
try {
|
|
701
|
+
doFoo();
|
|
702
|
+
doBar();
|
|
703
|
+
} finally {
|
|
704
|
+
doBaz();
|
|
705
|
+
}
|
|
706
|
+
*/
|
|
707
|
+
|
|
708
|
+
scheduleAction('doFoo and throw', function() {
|
|
709
|
+
messages.push('foo');
|
|
710
|
+
throw new StubError;
|
|
711
|
+
}).
|
|
712
|
+
then(function() { schedulePush('bar'); }).
|
|
713
|
+
finally(function() { schedulePush('baz'); });
|
|
714
|
+
|
|
715
|
+
return waitForAbort().
|
|
716
|
+
then(assertIsStubError).
|
|
717
|
+
then(assertingMessages('foo', 'baz'));
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
it('secondTryFails', function() {
|
|
721
|
+
/* Model:
|
|
722
|
+
try {
|
|
723
|
+
doFoo();
|
|
724
|
+
doBar();
|
|
725
|
+
} finally {
|
|
726
|
+
doBaz();
|
|
727
|
+
}
|
|
728
|
+
*/
|
|
729
|
+
|
|
730
|
+
schedulePush('foo').
|
|
731
|
+
then(function() {
|
|
732
|
+
return scheduleAction('doBar and throw', function() {
|
|
733
|
+
messages.push('bar');
|
|
734
|
+
throw new StubError;
|
|
735
|
+
});
|
|
736
|
+
}).
|
|
737
|
+
finally(function() {
|
|
738
|
+
return schedulePush('baz');
|
|
739
|
+
});
|
|
740
|
+
return waitForAbort().
|
|
741
|
+
then(assertIsStubError).
|
|
742
|
+
then(assertingMessages('foo', 'bar', 'baz'));
|
|
844
743
|
});
|
|
845
|
-
|
|
744
|
+
});
|
|
846
745
|
|
|
847
|
-
|
|
848
|
-
|
|
746
|
+
describe('testTaskCallbacksInterruptFlow', function() {
|
|
747
|
+
it('(base case)', function() {
|
|
748
|
+
schedule('a').then(function() {
|
|
749
|
+
schedule('b');
|
|
750
|
+
});
|
|
751
|
+
schedule('c');
|
|
752
|
+
return waitForIdle().then(function() {
|
|
753
|
+
assertFlowHistory('a', 'b', 'c');
|
|
754
|
+
});
|
|
849
755
|
});
|
|
850
|
-
});
|
|
851
756
|
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
schedule('
|
|
757
|
+
it('taskDependsOnImmediatelyFulfilledPromise', function() {
|
|
758
|
+
scheduleAction('a', function() {
|
|
759
|
+
return promise.fulfilled();
|
|
760
|
+
}).then(function() {
|
|
761
|
+
schedule('b');
|
|
762
|
+
});
|
|
763
|
+
schedule('c');
|
|
764
|
+
return waitForIdle().then(function() {
|
|
765
|
+
assertFlowHistory('a', 'b', 'c');
|
|
857
766
|
});
|
|
858
|
-
a.then(function() { schedule('e'); });
|
|
859
767
|
});
|
|
860
|
-
schedule('f');
|
|
861
768
|
|
|
862
|
-
|
|
863
|
-
|
|
769
|
+
it('taskDependsOnPreviouslyFulfilledPromise', function() {
|
|
770
|
+
var aPromise = promise.fulfilled(123);
|
|
771
|
+
scheduleAction('a', function() {
|
|
772
|
+
return aPromise;
|
|
773
|
+
}).then(function(value) {
|
|
774
|
+
assert.equal(123, value);
|
|
775
|
+
schedule('b');
|
|
776
|
+
});
|
|
777
|
+
schedule('c');
|
|
778
|
+
return waitForIdle().then(function() {
|
|
779
|
+
assertFlowHistory('a', 'b', 'c');
|
|
780
|
+
});
|
|
864
781
|
});
|
|
865
|
-
});
|
|
866
782
|
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
783
|
+
it('taskDependsOnAsyncPromise', function() {
|
|
784
|
+
scheduleAction('a', function() {
|
|
785
|
+
return promise.delayed(25);
|
|
786
|
+
}).then(function() {
|
|
787
|
+
schedule('b');
|
|
788
|
+
});
|
|
789
|
+
schedule('c');
|
|
790
|
+
return waitForIdle().then(function() {
|
|
791
|
+
assertFlowHistory('a', 'b', 'c');
|
|
876
792
|
});
|
|
877
|
-
a.then(function() { schedule('h'); });
|
|
878
793
|
});
|
|
879
|
-
schedule('i');
|
|
880
794
|
|
|
881
|
-
|
|
882
|
-
|
|
795
|
+
it('promiseChainedToTaskInterruptFlow', function() {
|
|
796
|
+
schedule('a').then(function() {
|
|
797
|
+
return promise.fulfilled();
|
|
798
|
+
}).then(function() {
|
|
799
|
+
return promise.fulfilled();
|
|
800
|
+
}).then(function() {
|
|
801
|
+
schedule('b');
|
|
802
|
+
});
|
|
803
|
+
schedule('c');
|
|
804
|
+
return waitForIdle().then(function() {
|
|
805
|
+
assertFlowHistory('a', 'b', 'c');
|
|
806
|
+
});
|
|
883
807
|
});
|
|
884
|
-
});
|
|
885
|
-
});
|
|
886
808
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
809
|
+
it('nestedTaskCallbacksInterruptFlowWhenResolved', function() {
|
|
810
|
+
schedule('a').then(function() {
|
|
811
|
+
schedule('b').then(function() {
|
|
812
|
+
schedule('c');
|
|
813
|
+
});
|
|
814
|
+
});
|
|
815
|
+
schedule('d');
|
|
816
|
+
return waitForIdle().then(function() {
|
|
817
|
+
assertFlowHistory('a', 'b', 'c', 'd');
|
|
818
|
+
});
|
|
892
819
|
});
|
|
893
820
|
});
|
|
894
821
|
|
|
895
|
-
|
|
896
|
-
var count = 0;
|
|
897
|
-
scheduleWait(function() {
|
|
898
|
-
return ++count == 3;
|
|
899
|
-
}, 100, 'counting to 3');
|
|
822
|
+
describe('testDelayedNesting', function() {
|
|
900
823
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
824
|
+
it('1', function() {
|
|
825
|
+
var a = schedule('a');
|
|
826
|
+
schedule('b').then(function() {
|
|
827
|
+
a.then(function() { schedule('c'); });
|
|
828
|
+
schedule('d');
|
|
829
|
+
});
|
|
830
|
+
schedule('e');
|
|
905
831
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
832
|
+
return waitForIdle().then(function() {
|
|
833
|
+
assertFlowHistory('a', 'b', 'c', 'd', 'e');
|
|
834
|
+
});
|
|
835
|
+
});
|
|
909
836
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
837
|
+
it('2', function() {
|
|
838
|
+
var a = schedule('a');
|
|
839
|
+
schedule('b').then(function() {
|
|
840
|
+
a.then(function() { schedule('c'); });
|
|
841
|
+
schedule('d');
|
|
842
|
+
a.then(function() { schedule('e'); });
|
|
843
|
+
});
|
|
844
|
+
schedule('f');
|
|
914
845
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
return waitForIdle();
|
|
846
|
+
return waitForIdle().then(function() {
|
|
847
|
+
assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f');
|
|
848
|
+
});
|
|
919
849
|
});
|
|
920
|
-
});
|
|
921
850
|
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
851
|
+
it('3', function() {
|
|
852
|
+
var a = schedule('a');
|
|
853
|
+
schedule('b').then(function() {
|
|
854
|
+
a.then(function() { schedule('c'); });
|
|
855
|
+
a.then(function() { schedule('d'); });
|
|
856
|
+
});
|
|
857
|
+
schedule('e');
|
|
927
858
|
|
|
928
|
-
|
|
929
|
-
|
|
859
|
+
return waitForIdle().then(function() {
|
|
860
|
+
assertFlowHistory('a', 'b', 'c', 'd', 'e');
|
|
861
|
+
});
|
|
930
862
|
});
|
|
931
|
-
});
|
|
932
863
|
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
864
|
+
it('4', function() {
|
|
865
|
+
var a = schedule('a');
|
|
866
|
+
schedule('b').then(function() {
|
|
867
|
+
a.then(function() { schedule('c'); }).then(function() {
|
|
868
|
+
schedule('d');
|
|
869
|
+
});
|
|
870
|
+
a.then(function() { schedule('e'); });
|
|
938
871
|
});
|
|
939
|
-
|
|
940
|
-
schedule('post wait');
|
|
872
|
+
schedule('f');
|
|
941
873
|
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
'0: counting to 3', 'increment count',
|
|
946
|
-
'1: counting to 3', 'increment count',
|
|
947
|
-
'2: counting to 3', 'increment count',
|
|
948
|
-
'post wait');
|
|
874
|
+
return waitForIdle().then(function() {
|
|
875
|
+
assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f');
|
|
876
|
+
});
|
|
949
877
|
});
|
|
950
|
-
});
|
|
951
878
|
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
879
|
+
it('5', function() {
|
|
880
|
+
var a = schedule('a');
|
|
881
|
+
schedule('b').then(function() {
|
|
882
|
+
var c;
|
|
883
|
+
a.then(function() { c = schedule('c'); }).then(function() {
|
|
884
|
+
schedule('d');
|
|
885
|
+
a.then(function() { schedule('e'); });
|
|
886
|
+
c.then(function() { schedule('f'); });
|
|
887
|
+
schedule('g');
|
|
888
|
+
});
|
|
889
|
+
a.then(function() { schedule('h'); });
|
|
890
|
+
});
|
|
891
|
+
schedule('i');
|
|
959
892
|
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
'0: counting to 3', 'sub task',
|
|
964
|
-
'1: counting to 3', 'sub task',
|
|
965
|
-
'2: counting to 3', 'sub task',
|
|
966
|
-
'post wait');
|
|
893
|
+
return waitForIdle().then(function() {
|
|
894
|
+
assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i');
|
|
895
|
+
});
|
|
967
896
|
});
|
|
968
897
|
});
|
|
969
898
|
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
}
|
|
977
|
-
schedule('post wait');
|
|
899
|
+
describe('testWaiting', function() {
|
|
900
|
+
it('onAConditionThatIsAlwaysTrue', function() {
|
|
901
|
+
scheduleWait(function() { return true;}, 0, 'waiting on true');
|
|
902
|
+
return waitForIdle().then(function() {
|
|
903
|
+
assertFlowHistory('0: waiting on true');
|
|
904
|
+
});
|
|
905
|
+
});
|
|
978
906
|
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
'post wait');
|
|
985
|
-
});
|
|
986
|
-
});
|
|
907
|
+
it('aSimpleCountingCondition', function() {
|
|
908
|
+
var count = 0;
|
|
909
|
+
scheduleWait(function() {
|
|
910
|
+
return ++count == 3;
|
|
911
|
+
}, 100, 'counting to 3');
|
|
987
912
|
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
schedule('post wait');
|
|
913
|
+
return waitForIdle().then(function() {
|
|
914
|
+
assert.equal(3, count);
|
|
915
|
+
});
|
|
916
|
+
});
|
|
993
917
|
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
assertFlowHistory('0: goes boom', 'post wait');
|
|
998
|
-
});
|
|
999
|
-
});
|
|
918
|
+
it('aConditionThatReturnsAPromise', function() {
|
|
919
|
+
var d = new promise.Deferred();
|
|
920
|
+
var count = 0;
|
|
1000
921
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
}, 0, 'goes boom').then(callbacks.callback, callbacks.errback);
|
|
1006
|
-
schedule('post wait');
|
|
922
|
+
scheduleWait(function() {
|
|
923
|
+
count += 1;
|
|
924
|
+
return d.promise;
|
|
925
|
+
}, 0, 'waiting for promise');
|
|
1007
926
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
927
|
+
return timeout(50).then(function() {
|
|
928
|
+
assert.equal(1, count);
|
|
929
|
+
d.fulfill(123);
|
|
930
|
+
return waitForIdle();
|
|
931
|
+
});
|
|
932
|
+
});
|
|
1014
933
|
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
schedule('post wait');
|
|
934
|
+
it('aConditionThatReturnsAPromise_2', function() {
|
|
935
|
+
var count = 0;
|
|
936
|
+
scheduleWait(function() {
|
|
937
|
+
return promise.fulfilled(++count == 3);
|
|
938
|
+
}, 100, 'waiting for promise');
|
|
1021
939
|
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
940
|
+
return waitForIdle().then(function() {
|
|
941
|
+
assert.equal(3, count);
|
|
942
|
+
});
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
it('aConditionThatReturnsATaskResult', function() {
|
|
946
|
+
var count = 0;
|
|
947
|
+
scheduleWait(function() {
|
|
948
|
+
return scheduleAction('increment count', function() {
|
|
949
|
+
return ++count == 3;
|
|
1026
950
|
});
|
|
1027
|
-
|
|
951
|
+
}, 100, 'counting to 3');
|
|
952
|
+
schedule('post wait');
|
|
953
|
+
|
|
954
|
+
return waitForIdle().then(function() {
|
|
955
|
+
assert.equal(3, count);
|
|
956
|
+
assertFlowHistory(
|
|
957
|
+
'0: counting to 3', 'increment count',
|
|
958
|
+
'1: counting to 3', 'increment count',
|
|
959
|
+
'2: counting to 3', 'increment count',
|
|
960
|
+
'post wait');
|
|
961
|
+
});
|
|
962
|
+
});
|
|
1028
963
|
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
964
|
+
it('conditionContainsASubtask', function() {
|
|
965
|
+
var count = 0;
|
|
966
|
+
scheduleWait(function() {
|
|
967
|
+
schedule('sub task');
|
|
968
|
+
return ++count == 3;
|
|
969
|
+
}, 100, 'counting to 3');
|
|
970
|
+
schedule('post wait');
|
|
971
|
+
|
|
972
|
+
return waitForIdle().then(function() {
|
|
973
|
+
assert.equal(3, count);
|
|
974
|
+
assertFlowHistory(
|
|
975
|
+
'0: counting to 3', 'sub task',
|
|
976
|
+
'1: counting to 3', 'sub task',
|
|
977
|
+
'2: counting to 3', 'sub task',
|
|
978
|
+
'post wait');
|
|
1037
979
|
});
|
|
1038
|
-
}
|
|
1039
|
-
schedule('post wait');
|
|
980
|
+
});
|
|
1040
981
|
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
982
|
+
it('cancelsWaitIfScheduledTaskFails', function() {
|
|
983
|
+
var pair = callbackPair(null, assertIsStubError);
|
|
984
|
+
scheduleWait(function() {
|
|
985
|
+
scheduleAction('boom', throwStubError);
|
|
986
|
+
schedule('this should not run');
|
|
987
|
+
return true;
|
|
988
|
+
}, 100, 'waiting to go boom').then(pair.callback, pair.errback);
|
|
989
|
+
schedule('post wait');
|
|
990
|
+
|
|
991
|
+
return waitForIdle().
|
|
992
|
+
then(pair.assertErrback).
|
|
993
|
+
then(function() {
|
|
994
|
+
assertFlowHistory(
|
|
995
|
+
'0: waiting to go boom', 'boom',
|
|
996
|
+
'post wait');
|
|
997
|
+
});
|
|
1047
998
|
});
|
|
1048
|
-
});
|
|
1049
999
|
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
}, 100, 'counting to 3');
|
|
1056
|
-
schedule('post wait');
|
|
1000
|
+
it('failsIfConditionThrows', function() {
|
|
1001
|
+
var callbacks = callbackPair(null, assertIsStubError);
|
|
1002
|
+
scheduleWait(throwStubError, 0, 'goes boom').
|
|
1003
|
+
then(callbacks.callback, callbacks.errback);
|
|
1004
|
+
schedule('post wait');
|
|
1057
1005
|
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
'2: counting to 3', 'increment count',
|
|
1064
|
-
'3: counting to 3', 'increment count',
|
|
1065
|
-
'post wait');
|
|
1006
|
+
return waitForIdle().
|
|
1007
|
+
then(callbacks.assertErrback).
|
|
1008
|
+
then(function() {
|
|
1009
|
+
assertFlowHistory('0: goes boom', 'post wait');
|
|
1010
|
+
});
|
|
1066
1011
|
});
|
|
1067
|
-
});
|
|
1068
1012
|
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
return done;
|
|
1076
|
-
}, 0);
|
|
1013
|
+
it('failsIfConditionReturnsARejectedPromise', function() {
|
|
1014
|
+
var callbacks = callbackPair(null, assertIsStubError);
|
|
1015
|
+
scheduleWait(function() {
|
|
1016
|
+
return promise.rejected(new StubError);
|
|
1017
|
+
}, 0, 'goes boom').then(callbacks.callback, callbacks.errback);
|
|
1018
|
+
schedule('post wait');
|
|
1077
1019
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
return waitResult;
|
|
1020
|
+
return waitForIdle().
|
|
1021
|
+
then(callbacks.assertErrback).
|
|
1022
|
+
then(function() {
|
|
1023
|
+
assertFlowHistory('0: goes boom', 'post wait');
|
|
1024
|
+
});
|
|
1084
1025
|
});
|
|
1085
|
-
});
|
|
1086
1026
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1027
|
+
it('failsIfConditionHasUnhandledRejection', function() {
|
|
1028
|
+
var callbacks = callbackPair(null, assertIsStubError);
|
|
1029
|
+
scheduleWait(function() {
|
|
1030
|
+
promise.controlFlow().execute(throwStubError);
|
|
1031
|
+
}, 0, 'goes boom').then(callbacks.callback, callbacks.errback);
|
|
1032
|
+
schedule('post wait');
|
|
1033
|
+
|
|
1034
|
+
return waitForIdle().
|
|
1035
|
+
then(callbacks.assertErrback).
|
|
1036
|
+
then(function() {
|
|
1037
|
+
assertFlowHistory('0: goes boom', 'post wait');
|
|
1038
|
+
});
|
|
1094
1039
|
});
|
|
1095
1040
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1041
|
+
it('failsIfConditionHasAFailedSubtask', function() {
|
|
1042
|
+
var callbacks = callbackPair(null, assertIsStubError);
|
|
1043
|
+
var count = 0;
|
|
1044
|
+
scheduleWait(function() {
|
|
1045
|
+
scheduleAction('maybe throw', function() {
|
|
1046
|
+
if (++count == 2) {
|
|
1047
|
+
throw new StubError;
|
|
1048
|
+
}
|
|
1049
|
+
});
|
|
1050
|
+
}, 100, 'waiting').then(callbacks.callback, callbacks.errback);
|
|
1051
|
+
schedule('post wait');
|
|
1052
|
+
|
|
1053
|
+
return waitForIdle().then(function() {
|
|
1054
|
+
assert.equal(2, count);
|
|
1055
|
+
assertFlowHistory(
|
|
1056
|
+
'0: waiting', 'maybe throw',
|
|
1057
|
+
'1: waiting', 'maybe throw',
|
|
1058
|
+
'post wait');
|
|
1059
|
+
});
|
|
1102
1060
|
});
|
|
1103
|
-
});
|
|
1104
1061
|
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
default:
|
|
1123
|
-
fail('unexpected polling count: ' + count);
|
|
1124
|
-
}
|
|
1125
|
-
assert.ok(
|
|
1126
|
-
/^counting to 3\nWait timed out after \d+ms$/.test(e.message));
|
|
1062
|
+
it('pollingLoopWaitsForAllScheduledTasksInCondition', function() {
|
|
1063
|
+
var count = 0;
|
|
1064
|
+
scheduleWait(function() {
|
|
1065
|
+
scheduleAction('increment count', function() { ++count; });
|
|
1066
|
+
return count >= 3;
|
|
1067
|
+
}, 100, 'counting to 3');
|
|
1068
|
+
schedule('post wait');
|
|
1069
|
+
|
|
1070
|
+
return waitForIdle().then(function() {
|
|
1071
|
+
assert.equal(4, count);
|
|
1072
|
+
assertFlowHistory(
|
|
1073
|
+
'0: counting to 3', 'increment count',
|
|
1074
|
+
'1: counting to 3', 'increment count',
|
|
1075
|
+
'2: counting to 3', 'increment count',
|
|
1076
|
+
'3: counting to 3', 'increment count',
|
|
1077
|
+
'post wait');
|
|
1078
|
+
});
|
|
1127
1079
|
});
|
|
1128
|
-
});
|
|
1129
1080
|
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1081
|
+
it('waitsForeverOnAZeroTimeout', function() {
|
|
1082
|
+
var done = false;
|
|
1083
|
+
setTimeout(function() {
|
|
1084
|
+
done = true;
|
|
1085
|
+
}, 150);
|
|
1086
|
+
var waitResult = scheduleWait(function() {
|
|
1087
|
+
return done;
|
|
1088
|
+
}, 0);
|
|
1089
|
+
|
|
1090
|
+
return timeout(75).then(function() {
|
|
1091
|
+
assert.ok(!done);
|
|
1092
|
+
return timeout(100);
|
|
1093
|
+
}).then(function() {
|
|
1094
|
+
assert.ok(done);
|
|
1095
|
+
return waitResult;
|
|
1096
|
+
});
|
|
1097
|
+
});
|
|
1136
1098
|
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1099
|
+
it('waitsForeverIfTimeoutOmitted', function() {
|
|
1100
|
+
var done = false;
|
|
1101
|
+
setTimeout(function() {
|
|
1102
|
+
done = true;
|
|
1103
|
+
}, 150);
|
|
1104
|
+
var waitResult = scheduleWait(function() {
|
|
1105
|
+
return done;
|
|
1106
|
+
});
|
|
1144
1107
|
|
|
1145
|
-
|
|
1146
|
-
|
|
1108
|
+
return timeout(75).then(function() {
|
|
1109
|
+
assert.ok(!done);
|
|
1110
|
+
return timeout(100);
|
|
1111
|
+
}).then(function() {
|
|
1112
|
+
assert.ok(done);
|
|
1113
|
+
return waitResult;
|
|
1114
|
+
});
|
|
1147
1115
|
});
|
|
1148
|
-
});
|
|
1149
1116
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1117
|
+
it('timesOut_nonZeroTimeout', function() {
|
|
1118
|
+
var count = 0;
|
|
1119
|
+
scheduleWait(function() {
|
|
1120
|
+
count += 1;
|
|
1121
|
+
var ms = count === 2 ? 65 : 5;
|
|
1122
|
+
return promise.delayed(ms).then(function() {
|
|
1123
|
+
return false;
|
|
1157
1124
|
});
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1125
|
+
}, 60, 'counting to 3');
|
|
1126
|
+
return waitForAbort().then(function(e) {
|
|
1127
|
+
switch (count) {
|
|
1128
|
+
case 1:
|
|
1129
|
+
assertFlowHistory('0: counting to 3');
|
|
1130
|
+
break;
|
|
1131
|
+
case 2:
|
|
1132
|
+
assertFlowHistory('0: counting to 3', '1: counting to 3');
|
|
1133
|
+
break;
|
|
1134
|
+
default:
|
|
1135
|
+
fail('unexpected polling count: ' + count);
|
|
1136
|
+
}
|
|
1137
|
+
assert.ok(e instanceof TimeoutError, 'Unexpected error: ' + e);
|
|
1138
|
+
assert.ok(
|
|
1139
|
+
/^counting to 3\nWait timed out after \d+ms$/.test(e.message));
|
|
1140
|
+
});
|
|
1167
1141
|
});
|
|
1168
|
-
});
|
|
1169
1142
|
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1143
|
+
it('shouldFailIfConditionReturnsARejectedPromise', function() {
|
|
1144
|
+
scheduleWait(function() {
|
|
1145
|
+
return promise.rejected(new StubError);
|
|
1146
|
+
}, 100, 'returns rejected promise on first pass');
|
|
1147
|
+
return waitForAbort().then(assertIsStubError);
|
|
1173
1148
|
});
|
|
1174
|
-
flow.wait(function() { return true;}, 0);
|
|
1175
|
-
flow.wait(promise.fulfilled(), 0);
|
|
1176
|
-
return waitForIdle();
|
|
1177
|
-
});
|
|
1178
1149
|
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1150
|
+
it('scheduleWithIntermittentWaits', function() {
|
|
1151
|
+
schedule('a');
|
|
1152
|
+
scheduleWait(function() { return true; }, 0, 'wait 1');
|
|
1153
|
+
schedule('b');
|
|
1154
|
+
scheduleWait(function() { return true; }, 0, 'wait 2');
|
|
1155
|
+
schedule('c');
|
|
1156
|
+
scheduleWait(function() { return true; }, 0, 'wait 3');
|
|
1157
|
+
|
|
1158
|
+
return waitForIdle().then(function() {
|
|
1159
|
+
assertFlowHistory('a', '0: wait 1', 'b', '0: wait 2', 'c', '0: wait 3');
|
|
1160
|
+
});
|
|
1186
1161
|
});
|
|
1187
|
-
|
|
1188
|
-
|
|
1162
|
+
|
|
1163
|
+
it('scheduleWithIntermittentAndNestedWaits', function() {
|
|
1164
|
+
schedule('a');
|
|
1165
|
+
scheduleWait(function() { return true; }, 0, 'wait 1').
|
|
1166
|
+
then(function() {
|
|
1167
|
+
schedule('d');
|
|
1168
|
+
scheduleWait(function() { return true; }, 0, 'wait 2');
|
|
1169
|
+
schedule('e');
|
|
1170
|
+
});
|
|
1171
|
+
schedule('b');
|
|
1172
|
+
scheduleWait(function() { return true; }, 0, 'wait 3');
|
|
1173
|
+
schedule('c');
|
|
1174
|
+
scheduleWait(function() { return true; }, 0, 'wait 4');
|
|
1175
|
+
|
|
1176
|
+
return waitForIdle().then(function() {
|
|
1177
|
+
assertFlowHistory(
|
|
1178
|
+
'a', '0: wait 1', 'd', '0: wait 2', 'e', 'b', '0: wait 3', 'c',
|
|
1179
|
+
'0: wait 4');
|
|
1180
|
+
});
|
|
1189
1181
|
});
|
|
1190
|
-
});
|
|
1191
1182
|
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1183
|
+
it('requiresConditionToBeAPromiseOrFunction', function() {
|
|
1184
|
+
assert.throws(function() {
|
|
1185
|
+
flow.wait(1234, 0);
|
|
1186
|
+
});
|
|
1187
|
+
flow.wait(function() { return true;}, 0);
|
|
1188
|
+
flow.wait(promise.fulfilled(), 0);
|
|
1189
|
+
return waitForIdle();
|
|
1198
1190
|
});
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1191
|
+
|
|
1192
|
+
it('promiseThatDoesNotResolveBeforeTimeout', function() {
|
|
1193
|
+
var d = promise.defer();
|
|
1194
|
+
flow.wait(d.promise, 5).then(fail, function(e) {
|
|
1195
|
+
assert.ok(e instanceof TimeoutError, 'Unexpected error: ' + e);
|
|
1196
|
+
assert.ok(
|
|
1197
|
+
/Timed out waiting for promise to resolve after \d+ms/
|
|
1198
|
+
.test(e.message),
|
|
1199
|
+
'unexpected error message: ' + e.message);
|
|
1200
|
+
});
|
|
1201
|
+
return waitForIdle();
|
|
1210
1202
|
});
|
|
1211
1203
|
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1204
|
+
it('unboundedWaitOnPromiseResolution', function() {
|
|
1205
|
+
var messages = [];
|
|
1206
|
+
var d = promise.defer();
|
|
1207
|
+
var waitResult = flow.wait(d.promise).then(function(value) {
|
|
1208
|
+
messages.push('b');
|
|
1209
|
+
assert.equal(1234, value);
|
|
1210
|
+
});
|
|
1211
|
+
setTimeout(function() {
|
|
1212
|
+
messages.push('a');
|
|
1213
|
+
}, 5);
|
|
1215
1214
|
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
schedule('b');
|
|
1215
|
+
timeout(10).then(function() {
|
|
1216
|
+
assert.deepEqual(['a'], messages);
|
|
1217
|
+
d.fulfill(1234);
|
|
1218
|
+
return waitResult;
|
|
1219
|
+
}).then(function() {
|
|
1220
|
+
assert.deepEqual(['a', 'b'], messages);
|
|
1221
|
+
});
|
|
1224
1222
|
|
|
1225
|
-
|
|
1226
|
-
assertFlowHistory('a', 'sub-tasks', 'c', 'd', 'b');
|
|
1223
|
+
return waitForIdle();
|
|
1227
1224
|
});
|
|
1228
1225
|
});
|
|
1229
1226
|
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
scheduleAction('sub-sub-tasks', function() {
|
|
1227
|
+
describe('testSubtasks', function() {
|
|
1228
|
+
it('(base case)', function() {
|
|
1229
|
+
schedule('a');
|
|
1230
|
+
scheduleAction('sub-tasks', function() {
|
|
1235
1231
|
schedule('c');
|
|
1236
1232
|
schedule('d');
|
|
1237
1233
|
});
|
|
1238
|
-
schedule('
|
|
1239
|
-
});
|
|
1240
|
-
schedule('f');
|
|
1234
|
+
schedule('b');
|
|
1241
1235
|
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1236
|
+
return waitForIdle().then(function() {
|
|
1237
|
+
assertFlowHistory('a', 'sub-tasks', 'c', 'd', 'b');
|
|
1238
|
+
});
|
|
1245
1239
|
});
|
|
1246
|
-
});
|
|
1247
1240
|
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1241
|
+
it('nesting', function() {
|
|
1242
|
+
schedule('a');
|
|
1243
|
+
scheduleAction('sub-tasks', function() {
|
|
1244
|
+
schedule('b');
|
|
1245
|
+
scheduleAction('sub-sub-tasks', function() {
|
|
1246
|
+
schedule('c');
|
|
1247
|
+
schedule('d');
|
|
1248
|
+
});
|
|
1249
|
+
schedule('e');
|
|
1250
|
+
});
|
|
1251
|
+
schedule('f');
|
|
1254
1252
|
|
|
1255
|
-
|
|
1256
|
-
|
|
1253
|
+
return waitForIdle().then(function() {
|
|
1254
|
+
assertFlowHistory(
|
|
1255
|
+
'a', 'sub-tasks', 'b', 'sub-sub-tasks', 'c', 'd', 'e', 'f');
|
|
1256
|
+
});
|
|
1257
1257
|
});
|
|
1258
|
-
});
|
|
1259
1258
|
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1259
|
+
it('taskReturnsSubTaskResult_1', function() {
|
|
1260
|
+
schedule('a');
|
|
1261
|
+
scheduleAction('sub-tasks', function() {
|
|
1262
|
+
return schedule('c');
|
|
1263
|
+
});
|
|
1264
|
+
schedule('b');
|
|
1265
1265
|
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1266
|
+
return waitForIdle().then(function() {
|
|
1267
|
+
assertFlowHistory('a', 'sub-tasks', 'c', 'b');
|
|
1268
|
+
});
|
|
1269
1269
|
});
|
|
1270
|
-
});
|
|
1271
1270
|
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1271
|
+
it('taskReturnsSubTaskResult_2', function() {
|
|
1272
|
+
let pair = callbackPair((value) => assert.equal(123, value));
|
|
1273
|
+
schedule('a');
|
|
1274
|
+
schedule('sub-tasks', promise.fulfilled(123)).then(pair.callback);
|
|
1275
|
+
schedule('b');
|
|
1276
|
+
|
|
1277
|
+
return waitForIdle().then(function() {
|
|
1278
|
+
assertFlowHistory('a', 'sub-tasks','b');
|
|
1279
|
+
pair.assertCallback();
|
|
1276
1280
|
});
|
|
1277
1281
|
});
|
|
1278
|
-
schedule('c');
|
|
1279
|
-
return waitForIdle().then(function() {
|
|
1280
|
-
assertFlowHistory('a', 'b', 'c');
|
|
1281
|
-
});
|
|
1282
|
-
});
|
|
1283
1282
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1283
|
+
it('taskReturnsPromiseThatDependsOnSubtask_1', function() {
|
|
1284
|
+
scheduleAction('a', function() {
|
|
1285
|
+
return promise.delayed(10).then(function() {
|
|
1286
|
+
schedule('b');
|
|
1287
|
+
});
|
|
1288
|
+
});
|
|
1289
|
+
schedule('c');
|
|
1290
|
+
return waitForIdle().then(function() {
|
|
1291
|
+
assertFlowHistory('a', 'b', 'c');
|
|
1288
1292
|
});
|
|
1289
1293
|
});
|
|
1290
|
-
schedule('c');
|
|
1291
|
-
return waitForIdle().then(function() {
|
|
1292
|
-
assertFlowHistory('a', 'b', 'c');
|
|
1293
|
-
});
|
|
1294
|
-
});
|
|
1295
1294
|
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1295
|
+
it('taskReturnsPromiseThatDependsOnSubtask_2', function() {
|
|
1296
|
+
scheduleAction('a', function() {
|
|
1297
|
+
return promise.fulfilled().then(function() {
|
|
1298
|
+
schedule('b');
|
|
1299
|
+
});
|
|
1300
|
+
});
|
|
1301
|
+
schedule('c');
|
|
1302
|
+
return waitForIdle().then(function() {
|
|
1303
|
+
assertFlowHistory('a', 'b', 'c');
|
|
1300
1304
|
});
|
|
1301
1305
|
});
|
|
1302
|
-
schedule('c');
|
|
1303
|
-
return waitForIdle().then(function() {
|
|
1304
|
-
assertFlowHistory('a', 'b', 'c');
|
|
1305
|
-
});
|
|
1306
|
-
});
|
|
1307
1306
|
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
return promise.delayed(5).then(function() {
|
|
1307
|
+
it('taskReturnsPromiseThatDependsOnSubtask_3', function() {
|
|
1308
|
+
scheduleAction('a', function() {
|
|
1309
|
+
return promise.delayed(10).then(function() {
|
|
1312
1310
|
return schedule('b');
|
|
1313
1311
|
});
|
|
1314
1312
|
});
|
|
1313
|
+
schedule('c');
|
|
1314
|
+
return waitForIdle().then(function() {
|
|
1315
|
+
assertFlowHistory('a', 'b', 'c');
|
|
1316
|
+
});
|
|
1315
1317
|
});
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1318
|
+
|
|
1319
|
+
it('taskReturnsPromiseThatDependsOnSubtask_4', function() {
|
|
1320
|
+
scheduleAction('a', function() {
|
|
1321
|
+
return promise.delayed(5).then(function() {
|
|
1322
|
+
return promise.delayed(5).then(function() {
|
|
1323
|
+
return schedule('b');
|
|
1324
|
+
});
|
|
1325
|
+
});
|
|
1326
|
+
});
|
|
1327
|
+
schedule('c');
|
|
1328
|
+
return waitForIdle().then(function() {
|
|
1329
|
+
assertFlowHistory('a', 'b', 'c');
|
|
1330
|
+
});
|
|
1319
1331
|
});
|
|
1320
|
-
});
|
|
1321
1332
|
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
return promise.delayed(5).then(function() {
|
|
1333
|
+
it('taskReturnsPromiseThatDependsOnSubtask_5', function() {
|
|
1334
|
+
scheduleAction('a', function() {
|
|
1325
1335
|
return promise.delayed(5).then(function() {
|
|
1326
1336
|
return promise.delayed(5).then(function() {
|
|
1327
1337
|
return promise.delayed(5).then(function() {
|
|
1328
|
-
return
|
|
1338
|
+
return promise.delayed(5).then(function() {
|
|
1339
|
+
return schedule('b');
|
|
1340
|
+
});
|
|
1329
1341
|
});
|
|
1330
1342
|
});
|
|
1331
1343
|
});
|
|
1332
1344
|
});
|
|
1345
|
+
schedule('c');
|
|
1346
|
+
return waitForIdle().then(function() {
|
|
1347
|
+
assertFlowHistory('a', 'b', 'c');
|
|
1348
|
+
});
|
|
1333
1349
|
});
|
|
1334
|
-
schedule('c');
|
|
1335
|
-
return waitForIdle().then(function() {
|
|
1336
|
-
assertFlowHistory('a', 'b', 'c');
|
|
1337
|
-
});
|
|
1338
|
-
});
|
|
1339
1350
|
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
+
it('taskReturnsPromiseThatDependsOnSubtask_6', function() {
|
|
1352
|
+
scheduleAction('a', function() {
|
|
1353
|
+
return promise.delayed(5).
|
|
1354
|
+
then(function() { return promise.delayed(5) }).
|
|
1355
|
+
then(function() { return promise.delayed(5) }).
|
|
1356
|
+
then(function() { return promise.delayed(5) }).
|
|
1357
|
+
then(function() { return schedule('b'); });
|
|
1358
|
+
});
|
|
1359
|
+
schedule('c');
|
|
1360
|
+
return waitForIdle().then(function() {
|
|
1361
|
+
assertFlowHistory('a', 'b', 'c');
|
|
1362
|
+
});
|
|
1351
1363
|
});
|
|
1352
|
-
});
|
|
1353
1364
|
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1365
|
+
it('subTaskFails_1', function() {
|
|
1366
|
+
schedule('a');
|
|
1367
|
+
scheduleAction('sub-tasks', function() {
|
|
1368
|
+
scheduleAction('sub-task that fails', throwStubError);
|
|
1369
|
+
});
|
|
1370
|
+
schedule('should never execute');
|
|
1371
|
+
|
|
1372
|
+
return waitForAbort().
|
|
1373
|
+
then(assertIsStubError).
|
|
1374
|
+
then(function() {
|
|
1375
|
+
assertFlowHistory('a', 'sub-tasks', 'sub-task that fails');
|
|
1376
|
+
});
|
|
1358
1377
|
});
|
|
1359
|
-
schedule('should never execute');
|
|
1360
1378
|
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1379
|
+
it('subTaskFails_2', function() {
|
|
1380
|
+
schedule('a');
|
|
1381
|
+
scheduleAction('sub-tasks', function() {
|
|
1382
|
+
return promise.rejected(new StubError);
|
|
1383
|
+
});
|
|
1384
|
+
schedule('should never execute');
|
|
1367
1385
|
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1386
|
+
return waitForAbort().
|
|
1387
|
+
then(assertIsStubError).
|
|
1388
|
+
then(function() {
|
|
1389
|
+
assertFlowHistory('a', 'sub-tasks');
|
|
1390
|
+
});
|
|
1372
1391
|
});
|
|
1373
|
-
schedule('should never execute');
|
|
1374
|
-
|
|
1375
|
-
return waitForAbort().
|
|
1376
|
-
then(assertIsStubError).
|
|
1377
|
-
then(function() {
|
|
1378
|
-
assertFlowHistory('a', 'sub-tasks');
|
|
1379
|
-
});
|
|
1380
|
-
});
|
|
1381
1392
|
|
|
1382
|
-
|
|
1383
|
-
|
|
1393
|
+
it('subTaskFails_3', function() {
|
|
1394
|
+
var callbacks = callbackPair(null, assertIsStubError);
|
|
1384
1395
|
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1396
|
+
schedule('a');
|
|
1397
|
+
scheduleAction('sub-tasks', function() {
|
|
1398
|
+
return promise.rejected(new StubError);
|
|
1399
|
+
}).then(callbacks.callback, callbacks.errback);
|
|
1400
|
+
schedule('b');
|
|
1390
1401
|
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1402
|
+
return waitForIdle().
|
|
1403
|
+
then(function() {
|
|
1404
|
+
assertFlowHistory('a', 'sub-tasks', 'b');
|
|
1405
|
+
callbacks.assertErrback();
|
|
1406
|
+
});
|
|
1407
|
+
});
|
|
1396
1408
|
});
|
|
1397
|
-
});
|
|
1398
1409
|
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1410
|
+
describe('testEventLoopWaitsOnPendingPromiseRejections', function() {
|
|
1411
|
+
it('oneRejection', function() {
|
|
1412
|
+
var d = new promise.Deferred;
|
|
1413
|
+
scheduleAction('one', function() {
|
|
1414
|
+
return d.promise;
|
|
1415
|
+
});
|
|
1416
|
+
scheduleAction('two', function() {});
|
|
1417
|
+
|
|
1418
|
+
return timeout(50).then(function() {
|
|
1419
|
+
assertFlowHistory('one');
|
|
1420
|
+
d.reject(new StubError);
|
|
1421
|
+
return waitForAbort();
|
|
1422
|
+
}).
|
|
1423
|
+
then(assertIsStubError).
|
|
1424
|
+
then(function() {
|
|
1425
|
+
assertFlowHistory('one');
|
|
1426
|
+
});
|
|
1404
1427
|
});
|
|
1405
|
-
scheduleAction('two', function() {});
|
|
1406
1428
|
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1429
|
+
it('multipleRejections', function() {
|
|
1430
|
+
var once = Error('once');
|
|
1431
|
+
var twice = Error('twice');
|
|
1432
|
+
|
|
1433
|
+
scheduleAction('one', function() {
|
|
1434
|
+
promise.rejected(once);
|
|
1435
|
+
promise.rejected(twice);
|
|
1436
|
+
});
|
|
1437
|
+
var twoResult = scheduleAction('two', function() {});
|
|
1438
|
+
|
|
1439
|
+
flow.removeAllListeners(
|
|
1440
|
+
promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
|
|
1441
|
+
return new NativePromise(function(fulfill, reject) {
|
|
1442
|
+
setTimeout(function() {
|
|
1443
|
+
reject(Error('Should have reported the two errors by now'));
|
|
1444
|
+
}, 50);
|
|
1445
|
+
flow.on(
|
|
1446
|
+
promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
|
|
1447
|
+
fulfill);
|
|
1448
|
+
}).then(function(e) {
|
|
1449
|
+
assert.ok(e instanceof promise.MultipleUnhandledRejectionError,
|
|
1450
|
+
'Not a MultipleUnhandledRejectionError');
|
|
1451
|
+
let errors = Array.from(e.errors);
|
|
1452
|
+
assert.deepEqual([once, twice], errors);
|
|
1453
|
+
assertFlowHistory('one');
|
|
1454
|
+
});
|
|
1415
1455
|
});
|
|
1416
1456
|
});
|
|
1417
1457
|
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1458
|
+
describe('testCancelsPromiseReturnedByCallbackIfFrameFails', function() {
|
|
1459
|
+
it('promiseCallback', function() {
|
|
1460
|
+
var chainPair = callbackPair(null, assertIsStubError);
|
|
1461
|
+
var deferredPair = callbackPair(null, function(e) {
|
|
1462
|
+
assert.equal('CancellationError: StubError', e.toString(),
|
|
1463
|
+
'callback result should be cancelled');
|
|
1464
|
+
});
|
|
1421
1465
|
|
|
1422
|
-
|
|
1423
|
-
promise.
|
|
1424
|
-
|
|
1466
|
+
var d = new promise.Deferred();
|
|
1467
|
+
d.promise.then(deferredPair.callback, deferredPair.errback);
|
|
1468
|
+
|
|
1469
|
+
promise.fulfilled().
|
|
1470
|
+
then(function() {
|
|
1471
|
+
scheduleAction('boom', throwStubError);
|
|
1472
|
+
schedule('this should not run');
|
|
1473
|
+
return d.promise;
|
|
1474
|
+
}).
|
|
1475
|
+
then(chainPair.callback, chainPair.errback);
|
|
1476
|
+
|
|
1477
|
+
return waitForIdle().then(function() {
|
|
1478
|
+
assertFlowHistory('boom');
|
|
1479
|
+
chainPair.assertErrback('chain errback not invoked');
|
|
1480
|
+
deferredPair.assertErrback('deferred errback not invoked');
|
|
1481
|
+
});
|
|
1425
1482
|
});
|
|
1426
|
-
var twoResult = scheduleAction('two', function() {});
|
|
1427
1483
|
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
}
|
|
1434
|
-
flow.on(
|
|
1435
|
-
promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
|
|
1436
|
-
fulfill);
|
|
1437
|
-
}).then(function(e) {
|
|
1438
|
-
assert.ok(e instanceof promise.MultipleUnhandledRejectionError,
|
|
1439
|
-
'Not a MultipleUnhandledRejectionError');
|
|
1440
|
-
let errors = Array.from(e.errors);
|
|
1441
|
-
assert.deepEqual([once, twice], errors);
|
|
1442
|
-
assertFlowHistory('one');
|
|
1443
|
-
assert.ok(!twoResult.isPending(), 'Did not cancel the second task');
|
|
1444
|
-
});
|
|
1445
|
-
});
|
|
1446
|
-
});
|
|
1484
|
+
it('taskCallback', function() {
|
|
1485
|
+
var chainPair = callbackPair(null, assertIsStubError);
|
|
1486
|
+
var deferredPair = callbackPair(null, function(e) {
|
|
1487
|
+
assert.equal('CancellationError: StubError', e.toString(),
|
|
1488
|
+
'callback result should be cancelled');
|
|
1489
|
+
});
|
|
1447
1490
|
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1491
|
+
var d = new promise.Deferred();
|
|
1492
|
+
d.promise.then(deferredPair.callback, deferredPair.errback);
|
|
1493
|
+
|
|
1494
|
+
schedule('a').
|
|
1495
|
+
then(function() {
|
|
1496
|
+
scheduleAction('boom', throwStubError);
|
|
1497
|
+
schedule('this should not run');
|
|
1498
|
+
return d.promise;
|
|
1499
|
+
}).
|
|
1500
|
+
then(chainPair.callback, chainPair.errback);
|
|
1501
|
+
|
|
1502
|
+
return waitForIdle().then(function() {
|
|
1503
|
+
assertFlowHistory('a', 'boom');
|
|
1504
|
+
chainPair.assertErrback('chain errback not invoked');
|
|
1505
|
+
deferredPair.assertErrback('deferred errback not invoked');
|
|
1506
|
+
});
|
|
1454
1507
|
});
|
|
1508
|
+
});
|
|
1455
1509
|
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
promise.fulfilled().
|
|
1510
|
+
it('testMaintainsOrderInCallbacksWhenATaskReturnsAPromise', function() {
|
|
1511
|
+
schedule('__start__', promise.fulfilled()).
|
|
1460
1512
|
then(function() {
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1513
|
+
messages.push('a');
|
|
1514
|
+
schedulePush('b');
|
|
1515
|
+
messages.push('c');
|
|
1464
1516
|
}).
|
|
1465
|
-
then(
|
|
1517
|
+
then(function() {
|
|
1518
|
+
messages.push('d');
|
|
1519
|
+
});
|
|
1520
|
+
schedulePush('e');
|
|
1466
1521
|
|
|
1467
1522
|
return waitForIdle().then(function() {
|
|
1468
|
-
assertFlowHistory('
|
|
1469
|
-
|
|
1470
|
-
deferredPair.assertErrback('deferred errback not invoked');
|
|
1523
|
+
assertFlowHistory('__start__', 'b', 'e');
|
|
1524
|
+
assertMessages('a', 'c', 'b', 'd', 'e');
|
|
1471
1525
|
});
|
|
1472
1526
|
});
|
|
1473
1527
|
|
|
1474
|
-
it('
|
|
1475
|
-
var
|
|
1476
|
-
var
|
|
1477
|
-
assert.equal('CancellationError: StubError', e.toString(),
|
|
1478
|
-
'callback result should be cancelled');
|
|
1479
|
-
});
|
|
1528
|
+
it('testOwningFlowIsActivatedForExecutingTasks', function() {
|
|
1529
|
+
var defaultFlow = promise.controlFlow();
|
|
1530
|
+
var order = [];
|
|
1480
1531
|
|
|
1481
|
-
|
|
1482
|
-
|
|
1532
|
+
promise.createFlow(function(flow) {
|
|
1533
|
+
assertFlowIs(flow);
|
|
1534
|
+
order.push(0);
|
|
1483
1535
|
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
}).
|
|
1490
|
-
then(chainPair.callback, chainPair.errback);
|
|
1536
|
+
defaultFlow.execute(function() {
|
|
1537
|
+
assertFlowIs(defaultFlow);
|
|
1538
|
+
order.push(1);
|
|
1539
|
+
});
|
|
1540
|
+
});
|
|
1491
1541
|
|
|
1492
1542
|
return waitForIdle().then(function() {
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
deferredPair.assertErrback('deferred errback not invoked');
|
|
1543
|
+
assertFlowIs(defaultFlow);
|
|
1544
|
+
assert.deepEqual([0, 1], order);
|
|
1496
1545
|
});
|
|
1497
1546
|
});
|
|
1498
|
-
});
|
|
1499
1547
|
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
}).
|
|
1507
|
-
|
|
1508
|
-
|
|
1548
|
+
it('testCreateFlowReturnsPromisePairedWithCreatedFlow', function() {
|
|
1549
|
+
return new NativePromise(function(fulfill, reject) {
|
|
1550
|
+
var newFlow;
|
|
1551
|
+
promise.createFlow(function(flow) {
|
|
1552
|
+
newFlow = flow;
|
|
1553
|
+
assertFlowIs(newFlow);
|
|
1554
|
+
}).then(function() {
|
|
1555
|
+
assertFlowIs(newFlow);
|
|
1556
|
+
waitForIdle(newFlow).then(fulfill, reject);
|
|
1509
1557
|
});
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
return waitForIdle().then(function() {
|
|
1513
|
-
assertFlowHistory('__start__', 'b', 'e');
|
|
1514
|
-
assertMessages('a', 'c', 'b', 'd', 'e');
|
|
1558
|
+
});
|
|
1515
1559
|
});
|
|
1516
|
-
});
|
|
1517
|
-
|
|
1518
|
-
it('testOwningFlowIsActivatedForExecutingTasks', function() {
|
|
1519
|
-
var defaultFlow = promise.controlFlow();
|
|
1520
|
-
var order = [];
|
|
1521
1560
|
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
defaultFlow.execute(function() {
|
|
1561
|
+
it('testDeferredFactoriesCreateForActiveFlow_defaultFlow', function() {
|
|
1562
|
+
var e = Error();
|
|
1563
|
+
var defaultFlow = promise.controlFlow();
|
|
1564
|
+
promise.fulfilled().then(function() {
|
|
1527
1565
|
assertFlowIs(defaultFlow);
|
|
1528
|
-
order.push(1);
|
|
1529
1566
|
});
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
});
|
|
1537
|
-
|
|
1538
|
-
it('testCreateFlowReturnsPromisePairedWithCreatedFlow', function() {
|
|
1539
|
-
return new NativePromise(function(fulfill, reject) {
|
|
1540
|
-
var newFlow;
|
|
1541
|
-
promise.createFlow(function(flow) {
|
|
1542
|
-
newFlow = flow;
|
|
1543
|
-
assertFlowIs(newFlow);
|
|
1544
|
-
}).then(function() {
|
|
1545
|
-
assertFlowIs(newFlow);
|
|
1546
|
-
waitForIdle(newFlow).then(fulfill, reject);
|
|
1567
|
+
promise.rejected(e).then(null, function(err) {
|
|
1568
|
+
assert.equal(e, err);
|
|
1569
|
+
assertFlowIs(defaultFlow);
|
|
1570
|
+
});
|
|
1571
|
+
promise.defer().promise.then(function() {
|
|
1572
|
+
assertFlowIs(defaultFlow);
|
|
1547
1573
|
});
|
|
1548
|
-
});
|
|
1549
|
-
});
|
|
1550
1574
|
|
|
1551
|
-
|
|
1552
|
-
var e = Error();
|
|
1553
|
-
var defaultFlow = promise.controlFlow();
|
|
1554
|
-
promise.fulfilled().then(function() {
|
|
1555
|
-
assertFlowIs(defaultFlow);
|
|
1556
|
-
});
|
|
1557
|
-
promise.rejected(e).then(null, function(err) {
|
|
1558
|
-
assert.equal(e, err);
|
|
1559
|
-
assertFlowIs(defaultFlow);
|
|
1560
|
-
});
|
|
1561
|
-
promise.defer().promise.then(function() {
|
|
1562
|
-
assertFlowIs(defaultFlow);
|
|
1575
|
+
return waitForIdle();
|
|
1563
1576
|
});
|
|
1564
1577
|
|
|
1565
|
-
|
|
1566
|
-
|
|
1578
|
+
it('testDeferredFactoriesCreateForActiveFlow_newFlow', function() {
|
|
1579
|
+
var e = Error();
|
|
1580
|
+
var newFlow = new promise.ControlFlow;
|
|
1581
|
+
newFlow.execute(function() {
|
|
1582
|
+
promise.fulfilled().then(function() {
|
|
1583
|
+
assertFlowIs(newFlow);
|
|
1584
|
+
});
|
|
1567
1585
|
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
promise.fulfilled().then(function() {
|
|
1573
|
-
assertFlowIs(newFlow);
|
|
1574
|
-
});
|
|
1586
|
+
promise.rejected(e).then(null, function(err) {
|
|
1587
|
+
assert.equal(e, err);
|
|
1588
|
+
assertFlowIs(newFlow);
|
|
1589
|
+
});
|
|
1575
1590
|
|
|
1576
|
-
|
|
1577
|
-
|
|
1591
|
+
let d = promise.defer();
|
|
1592
|
+
d.promise.then(function() {
|
|
1593
|
+
assertFlowIs(newFlow);
|
|
1594
|
+
});
|
|
1595
|
+
d.fulfill();
|
|
1596
|
+
}).then(function() {
|
|
1578
1597
|
assertFlowIs(newFlow);
|
|
1579
1598
|
});
|
|
1580
1599
|
|
|
1581
|
-
|
|
1582
|
-
d.promise.then(function() {
|
|
1583
|
-
assertFlowIs(newFlow);
|
|
1584
|
-
});
|
|
1585
|
-
d.fulfill();
|
|
1586
|
-
}).then(function() {
|
|
1587
|
-
assertFlowIs(newFlow);
|
|
1600
|
+
return waitForIdle(newFlow);
|
|
1588
1601
|
});
|
|
1589
1602
|
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
schedulePush('a', 'a');
|
|
1596
|
-
promise.controlFlow().timeout(250);
|
|
1597
|
-
schedulePush('b', 'b');
|
|
1603
|
+
it('testFlowsSynchronizeWithThemselvesNotEachOther', function() {
|
|
1604
|
+
var defaultFlow = promise.controlFlow();
|
|
1605
|
+
schedulePush('a', 'a');
|
|
1606
|
+
promise.controlFlow().timeout(500);
|
|
1607
|
+
schedulePush('b', 'b');
|
|
1598
1608
|
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1609
|
+
promise.createFlow(function(flow2) {
|
|
1610
|
+
assertFlowIs(flow2);
|
|
1611
|
+
schedulePush('c', 'c');
|
|
1612
|
+
schedulePush('d', 'd');
|
|
1613
|
+
});
|
|
1603
1614
|
|
|
1604
|
-
|
|
1605
|
-
|
|
1615
|
+
return waitForIdle().then(function() {
|
|
1616
|
+
assertMessages('a', 'c', 'd', 'b');
|
|
1617
|
+
});
|
|
1606
1618
|
});
|
|
1607
|
-
});
|
|
1608
1619
|
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1620
|
+
it('testUnhandledErrorsAreReportedToTheOwningFlow', function() {
|
|
1621
|
+
var error1 = Error('e1');
|
|
1622
|
+
var error2 = Error('e2');
|
|
1612
1623
|
|
|
1613
|
-
|
|
1614
|
-
|
|
1624
|
+
var defaultFlow = promise.controlFlow();
|
|
1625
|
+
defaultFlow.removeAllListeners('uncaughtException');
|
|
1615
1626
|
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1627
|
+
var flow1Error = defer();
|
|
1628
|
+
flow1Error.promise.then(function(value) {
|
|
1629
|
+
assert.equal(error2, value);
|
|
1630
|
+
});
|
|
1620
1631
|
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1632
|
+
var flow2Error = defer();
|
|
1633
|
+
flow2Error.promise.then(function(value) {
|
|
1634
|
+
assert.equal(error1, value);
|
|
1635
|
+
});
|
|
1625
1636
|
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1637
|
+
promise.createFlow(function(flow) {
|
|
1638
|
+
flow.once('uncaughtException', flow2Error.resolve);
|
|
1639
|
+
promise.rejected(error1);
|
|
1629
1640
|
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1641
|
+
defaultFlow.once('uncaughtException', flow1Error.resolve);
|
|
1642
|
+
defaultFlow.execute(function() {
|
|
1643
|
+
promise.rejected(error2);
|
|
1644
|
+
});
|
|
1633
1645
|
});
|
|
1634
|
-
});
|
|
1635
1646
|
|
|
1636
|
-
|
|
1637
|
-
|
|
1647
|
+
return NativePromise.all([flow1Error.promise, flow2Error.promise]);
|
|
1648
|
+
});
|
|
1638
1649
|
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1650
|
+
it('testCanSynchronizeFlowsByReturningPromiseFromOneToAnother', function() {
|
|
1651
|
+
var flow1 = new promise.ControlFlow;
|
|
1652
|
+
var flow1Done = defer();
|
|
1653
|
+
flow1.once('idle', flow1Done.resolve);
|
|
1654
|
+
flow1.once('uncaughtException', flow1Done.reject);
|
|
1644
1655
|
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1656
|
+
var flow2 = new promise.ControlFlow;
|
|
1657
|
+
var flow2Done = defer();
|
|
1658
|
+
flow2.once('idle', flow2Done.resolve);
|
|
1659
|
+
flow2.once('uncaughtException', flow2Done.reject);
|
|
1649
1660
|
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1661
|
+
flow1.execute(function() {
|
|
1662
|
+
schedulePush('a', 'a');
|
|
1663
|
+
return promise.delayed(25);
|
|
1664
|
+
}, 'start flow 1');
|
|
1654
1665
|
|
|
1655
|
-
flow2.execute(function() {
|
|
1656
|
-
schedulePush('b', 'b');
|
|
1657
|
-
schedulePush('c', 'c');
|
|
1658
1666
|
flow2.execute(function() {
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1667
|
+
schedulePush('b', 'b');
|
|
1668
|
+
schedulePush('c', 'c');
|
|
1669
|
+
flow2.execute(function() {
|
|
1670
|
+
return flow1.execute(function() {
|
|
1671
|
+
schedulePush('d', 'd');
|
|
1672
|
+
}, 'flow 1 task');
|
|
1673
|
+
}, 'inject flow1 result into flow2');
|
|
1674
|
+
schedulePush('e', 'e');
|
|
1675
|
+
}, 'start flow 2');
|
|
1676
|
+
|
|
1677
|
+
return NativePromise.all([flow1Done.promise, flow2Done.promise]).
|
|
1678
|
+
then(function() {
|
|
1679
|
+
assertMessages('a', 'b', 'c', 'd', 'e');
|
|
1680
|
+
});
|
|
1681
|
+
});
|
|
1671
1682
|
|
|
1672
|
-
|
|
1673
|
-
|
|
1683
|
+
it('testFramesWaitToCompleteForPendingRejections', function() {
|
|
1684
|
+
return new NativePromise(function(fulfill, reject) {
|
|
1674
1685
|
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1686
|
+
promise.controlFlow().execute(function() {
|
|
1687
|
+
promise.rejected(new StubError);
|
|
1688
|
+
}).then(fulfill, reject);
|
|
1678
1689
|
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1690
|
+
}).
|
|
1691
|
+
then(() => fail('expected to fail'), assertIsStubError);
|
|
1692
|
+
});
|
|
1682
1693
|
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1694
|
+
it('testSynchronizeErrorsPropagateToOuterFlow', function() {
|
|
1695
|
+
var outerFlow = new promise.ControlFlow;
|
|
1696
|
+
var innerFlow = new promise.ControlFlow;
|
|
1686
1697
|
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1698
|
+
var block = defer();
|
|
1699
|
+
innerFlow.execute(function() {
|
|
1700
|
+
return block.promise;
|
|
1701
|
+
}, 'block inner flow');
|
|
1691
1702
|
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1703
|
+
outerFlow.execute(function() {
|
|
1704
|
+
block.resolve();
|
|
1705
|
+
return innerFlow.execute(function() {
|
|
1706
|
+
promise.rejected(new StubError);
|
|
1707
|
+
}, 'trigger unhandled rejection error');
|
|
1708
|
+
}, 'run test');
|
|
1698
1709
|
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1710
|
+
return NativePromise.all([
|
|
1711
|
+
waitForIdle(innerFlow),
|
|
1712
|
+
waitForAbort(outerFlow).then(assertIsStubError)
|
|
1713
|
+
]);
|
|
1714
|
+
});
|
|
1704
1715
|
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1716
|
+
it('testFailsIfErrbackThrows', function() {
|
|
1717
|
+
promise.rejected('').then(null, throwStubError);
|
|
1718
|
+
return waitForAbort().then(assertIsStubError);
|
|
1719
|
+
});
|
|
1709
1720
|
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1721
|
+
it('testFailsIfCallbackReturnsRejectedPromise', function() {
|
|
1722
|
+
promise.fulfilled().then(function() {
|
|
1723
|
+
return promise.rejected(new StubError);
|
|
1724
|
+
});
|
|
1725
|
+
return waitForAbort().then(assertIsStubError);
|
|
1713
1726
|
});
|
|
1714
|
-
return waitForAbort().then(assertIsStubError);
|
|
1715
|
-
});
|
|
1716
1727
|
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1728
|
+
it('testAbortsFrameIfTaskFails', function() {
|
|
1729
|
+
promise.fulfilled().then(function() {
|
|
1730
|
+
promise.controlFlow().execute(throwStubError);
|
|
1731
|
+
});
|
|
1732
|
+
return waitForAbort().then(assertIsStubError);
|
|
1720
1733
|
});
|
|
1721
|
-
return waitForAbort().then(assertIsStubError);
|
|
1722
|
-
});
|
|
1723
1734
|
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1735
|
+
it('testAbortsFramePromisedChainedFromTaskIsNotHandled', function() {
|
|
1736
|
+
promise.fulfilled().then(function() {
|
|
1737
|
+
promise.controlFlow().execute(function() {}).
|
|
1738
|
+
then(throwStubError);
|
|
1739
|
+
});
|
|
1740
|
+
return waitForAbort().then(assertIsStubError);
|
|
1728
1741
|
});
|
|
1729
|
-
return waitForAbort().then(assertIsStubError);
|
|
1730
|
-
});
|
|
1731
1742
|
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1743
|
+
it('testTrapsChainedUnhandledRejectionsWithinAFrame', function() {
|
|
1744
|
+
var pair = callbackPair(null, assertIsStubError);
|
|
1745
|
+
promise.fulfilled().then(function() {
|
|
1746
|
+
promise.controlFlow().execute(function() {}).
|
|
1747
|
+
then(throwStubError);
|
|
1748
|
+
}).then(pair.callback, pair.errback);
|
|
1738
1749
|
|
|
1739
|
-
|
|
1740
|
-
|
|
1750
|
+
return waitForIdle().then(pair.assertErrback);
|
|
1751
|
+
});
|
|
1741
1752
|
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
return waitForIdle().
|
|
1753
|
-
then(pair.assertErrback).
|
|
1754
|
-
then(function() {
|
|
1755
|
-
assert.ok(!task1.isPending());
|
|
1756
|
-
pair = callbackPair();
|
|
1757
|
-
return task1.then(pair.callback, pair.errback);
|
|
1758
|
-
}).
|
|
1759
|
-
then(function() {
|
|
1760
|
-
pair.assertErrback();
|
|
1761
|
-
assert.ok(!task2.isPending());
|
|
1762
|
-
pair = callbackPair();
|
|
1763
|
-
return task2.then(pair.callback, pair.errback);
|
|
1764
|
-
}).
|
|
1765
|
-
then(function() {
|
|
1766
|
-
pair.assertErrback();
|
|
1767
|
-
});
|
|
1768
|
-
});
|
|
1753
|
+
it('testCancelsRemainingTasksIfFrameThrowsDuringScheduling', function() {
|
|
1754
|
+
var task1, task2;
|
|
1755
|
+
var pair = callbackPair(null, assertIsStubError);
|
|
1756
|
+
var flow = promise.controlFlow();
|
|
1757
|
+
flow.execute(function() {
|
|
1758
|
+
task1 = flow.execute(function() {});
|
|
1759
|
+
task2 = flow.execute(function() {});
|
|
1760
|
+
throw new StubError;
|
|
1761
|
+
}).then(pair.callback, pair.errback);
|
|
1769
1762
|
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
pair.assertErrback();
|
|
1763
|
+
return waitForIdle().
|
|
1764
|
+
then(pair.assertErrback).
|
|
1765
|
+
then(function() {
|
|
1766
|
+
pair = callbackPair();
|
|
1767
|
+
return task1.then(pair.callback, pair.errback);
|
|
1768
|
+
}).
|
|
1769
|
+
then(function() {
|
|
1770
|
+
pair.assertErrback();
|
|
1771
|
+
pair = callbackPair();
|
|
1772
|
+
return task2.then(pair.callback, pair.errback);
|
|
1773
|
+
}).
|
|
1774
|
+
then(function() {
|
|
1775
|
+
pair.assertErrback();
|
|
1776
|
+
});
|
|
1785
1777
|
});
|
|
1786
|
-
});
|
|
1787
1778
|
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1779
|
+
it('testCancelsRemainingTasksInFrameIfATaskFails', function() {
|
|
1780
|
+
var task;
|
|
1781
|
+
var pair = callbackPair(null, assertIsStubError);
|
|
1782
|
+
var flow = promise.controlFlow();
|
|
1783
|
+
flow.execute(function() {
|
|
1784
|
+
flow.execute(throwStubError);
|
|
1785
|
+
task = flow.execute(function() {});
|
|
1786
|
+
}).then(pair.callback, pair.errback);
|
|
1792
1787
|
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1788
|
+
return waitForIdle().then(pair.assertErrback).then(function() {
|
|
1789
|
+
pair = callbackPair();
|
|
1790
|
+
task.then(pair.callback, pair.errback);
|
|
1791
|
+
}).then(function() {
|
|
1792
|
+
pair.assertErrback();
|
|
1793
|
+
});
|
|
1798
1794
|
});
|
|
1799
1795
|
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1796
|
+
it('testDoesNotModifyRejectionErrorIfPromiseNotInsideAFlow', function() {
|
|
1797
|
+
var error = Error('original message');
|
|
1798
|
+
var originalStack = error.stack;
|
|
1799
|
+
var originalStr = error.toString();
|
|
1803
1800
|
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
messages.push(step + '.1');
|
|
1814
|
-
}).then(function() {
|
|
1815
|
-
messages.push(step + '.2');
|
|
1816
|
-
});
|
|
1817
|
-
})
|
|
1818
|
-
});
|
|
1819
|
-
return waitForIdle().then(function() {
|
|
1820
|
-
assert.deepEqual(
|
|
1821
|
-
['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'],
|
|
1822
|
-
messages);
|
|
1801
|
+
var pair = callbackPair(null, function(e) {
|
|
1802
|
+
assert.equal(error, e);
|
|
1803
|
+
assert.equal('original message', e.message);
|
|
1804
|
+
assert.equal(originalStack, e.stack);
|
|
1805
|
+
assert.equal(originalStr, e.toString());
|
|
1806
|
+
});
|
|
1807
|
+
|
|
1808
|
+
promise.rejected(error).then(pair.callback, pair.errback);
|
|
1809
|
+
return waitForIdle().then(pair.assertErrback);
|
|
1823
1810
|
});
|
|
1824
|
-
});
|
|
1825
1811
|
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
flow.execute(function() {}, step + '.2').then(function() {
|
|
1812
|
+
/** See https://github.com/SeleniumHQ/selenium/issues/444 */
|
|
1813
|
+
it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_1', function() {
|
|
1814
|
+
var messages = [];
|
|
1815
|
+
flow.execute(function() {
|
|
1816
|
+
return promise.fulfilled(['a', 'b', 'c', 'd']);
|
|
1817
|
+
}, 'start').then(function(steps) {
|
|
1818
|
+
steps.forEach(function(step) {
|
|
1819
|
+
promise.fulfilled(step)
|
|
1820
|
+
.then(function() {
|
|
1821
|
+
messages.push(step + '.1');
|
|
1822
|
+
}).then(function() {
|
|
1838
1823
|
messages.push(step + '.2');
|
|
1839
1824
|
});
|
|
1840
|
-
})
|
|
1841
|
-
})
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1825
|
+
})
|
|
1826
|
+
});
|
|
1827
|
+
return waitForIdle().then(function() {
|
|
1828
|
+
assert.deepEqual(
|
|
1829
|
+
['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'],
|
|
1830
|
+
messages);
|
|
1831
|
+
});
|
|
1847
1832
|
});
|
|
1848
|
-
});
|
|
1849
1833
|
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
messages.push(step + '.2');
|
|
1834
|
+
/** See https://github.com/SeleniumHQ/selenium/issues/444 */
|
|
1835
|
+
it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_2', function() {
|
|
1836
|
+
var messages = [];
|
|
1837
|
+
flow.execute(function() {
|
|
1838
|
+
return promise.fulfilled(['a', 'b', 'c', 'd']);
|
|
1839
|
+
}, 'start').then(function(steps) {
|
|
1840
|
+
steps.forEach(function(step) {
|
|
1841
|
+
promise.fulfilled(step)
|
|
1842
|
+
.then(function() {
|
|
1843
|
+
messages.push(step + '.1');
|
|
1844
|
+
}).then(function() {
|
|
1845
|
+
flow.execute(function() {}, step + '.2').then(function() {
|
|
1846
|
+
messages.push(step + '.2');
|
|
1847
|
+
});
|
|
1865
1848
|
});
|
|
1866
|
-
})
|
|
1867
|
-
})
|
|
1849
|
+
})
|
|
1850
|
+
});
|
|
1851
|
+
return waitForIdle().then(function() {
|
|
1852
|
+
assert.deepEqual(
|
|
1853
|
+
['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'],
|
|
1854
|
+
messages);
|
|
1855
|
+
});
|
|
1868
1856
|
});
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1857
|
+
|
|
1858
|
+
/** See https://github.com/SeleniumHQ/selenium/issues/444 */
|
|
1859
|
+
it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_3', function() {
|
|
1860
|
+
var messages = [];
|
|
1861
|
+
flow.execute(function() {
|
|
1862
|
+
return promise.fulfilled(['a', 'b', 'c', 'd']);
|
|
1863
|
+
}, 'start').then(function(steps) {
|
|
1864
|
+
steps.forEach(function(step) {
|
|
1865
|
+
promise.fulfilled(step)
|
|
1866
|
+
.then(function(){})
|
|
1867
|
+
.then(function() {
|
|
1868
|
+
messages.push(step + '.1');
|
|
1869
|
+
return flow.execute(function() {}, step + '.1');
|
|
1870
|
+
}).then(function() {
|
|
1871
|
+
flow.execute(function() {}, step + '.2').then(function(text) {
|
|
1872
|
+
messages.push(step + '.2');
|
|
1873
|
+
});
|
|
1874
|
+
});
|
|
1875
|
+
})
|
|
1876
|
+
});
|
|
1877
|
+
return waitForIdle().then(function() {
|
|
1878
|
+
assert.deepEqual(
|
|
1879
|
+
['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'],
|
|
1880
|
+
messages);
|
|
1881
|
+
});
|
|
1873
1882
|
});
|
|
1874
|
-
});
|
|
1875
1883
|
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1884
|
+
/** See https://github.com/SeleniumHQ/selenium/issues/363 */
|
|
1885
|
+
it('testTasksScheduledInASeparateTurnOfTheEventLoopGetASeparateTaskQueue_2', function() {
|
|
1886
|
+
scheduleAction('a', () => promise.delayed(10));
|
|
1887
|
+
schedule('b');
|
|
1888
|
+
setTimeout(() => schedule('c'), 0);
|
|
1881
1889
|
|
|
1882
|
-
|
|
1883
|
-
|
|
1890
|
+
return waitForIdle().then(function() {
|
|
1891
|
+
assertFlowHistory('a', 'c', 'b');
|
|
1892
|
+
});
|
|
1884
1893
|
});
|
|
1885
|
-
});
|
|
1886
1894
|
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
return waitForIdle().then(function() {
|
|
1899
|
-
assertFlowHistory('a', 'd', 'e', 'b', 'c', 'f');
|
|
1900
|
-
});
|
|
1901
|
-
});
|
|
1895
|
+
/** See https://github.com/SeleniumHQ/selenium/issues/363 */
|
|
1896
|
+
it('testTasksScheduledInASeparateTurnOfTheEventLoopGetASeparateTaskQueue_2', function() {
|
|
1897
|
+
scheduleAction('a', () => promise.delayed(10));
|
|
1898
|
+
schedule('b');
|
|
1899
|
+
schedule('c');
|
|
1900
|
+
setTimeout(function() {
|
|
1901
|
+
schedule('d');
|
|
1902
|
+
scheduleAction('e', () => promise.delayed(10));
|
|
1903
|
+
schedule('f');
|
|
1904
|
+
}, 0);
|
|
1902
1905
|
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
schedule('b');
|
|
1907
|
-
setTimeout(function() {
|
|
1908
|
-
scheduleAction('c', () => task1);
|
|
1909
|
-
schedule('d');
|
|
1910
|
-
}, 0);
|
|
1911
|
-
|
|
1912
|
-
return waitForIdle().then(function() {
|
|
1913
|
-
assertFlowHistory('a', 'c', 'd', 'b');
|
|
1906
|
+
return waitForIdle().then(function() {
|
|
1907
|
+
assertFlowHistory('a', 'd', 'e', 'b', 'c', 'f');
|
|
1908
|
+
});
|
|
1914
1909
|
});
|
|
1915
|
-
});
|
|
1916
1910
|
|
|
1917
|
-
|
|
1918
|
-
it('
|
|
1919
|
-
var
|
|
1920
|
-
|
|
1921
|
-
|
|
1911
|
+
/** See https://github.com/SeleniumHQ/selenium/issues/363 */
|
|
1912
|
+
it('testCanSynchronizeTasksFromAdjacentTaskQueues', function() {
|
|
1913
|
+
var task1 = scheduleAction('a', () => promise.delayed(10));
|
|
1914
|
+
schedule('b');
|
|
1915
|
+
setTimeout(function() {
|
|
1916
|
+
scheduleAction('c', () => task1);
|
|
1917
|
+
schedule('d');
|
|
1918
|
+
}, 0);
|
|
1922
1919
|
|
|
1923
1920
|
return waitForIdle().then(function() {
|
|
1924
|
-
|
|
1925
|
-
assertFlowHistory();
|
|
1926
|
-
return task1.catch(function(e) {
|
|
1927
|
-
assert.ok(e instanceof promise.CancellationError);
|
|
1928
|
-
assert.equal('no soup for you', e.message);
|
|
1929
|
-
});
|
|
1921
|
+
assertFlowHistory('a', 'c', 'd', 'b');
|
|
1930
1922
|
});
|
|
1931
1923
|
});
|
|
1932
1924
|
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1925
|
+
describe('testCancellingAScheduledTask', function() {
|
|
1926
|
+
it('1', function() {
|
|
1927
|
+
var called = false;
|
|
1928
|
+
var task1 = scheduleAction('a', () => called = true);
|
|
1929
|
+
task1.cancel('no soup for you');
|
|
1938
1930
|
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
assert.equal('no soup for you', e.message);
|
|
1931
|
+
return waitForIdle().then(function() {
|
|
1932
|
+
assert.ok(!called);
|
|
1933
|
+
assertFlowHistory();
|
|
1934
|
+
return task1.catch(function(e) {
|
|
1935
|
+
assert.ok(e instanceof promise.CancellationError);
|
|
1936
|
+
assert.equal('no soup for you', e.message);
|
|
1937
|
+
});
|
|
1947
1938
|
});
|
|
1948
1939
|
});
|
|
1949
|
-
});
|
|
1950
1940
|
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1941
|
+
it('2', function() {
|
|
1942
|
+
schedule('a');
|
|
1943
|
+
var called = false;
|
|
1944
|
+
var task2 = scheduleAction('b', () => called = true);
|
|
1945
|
+
schedule('c');
|
|
1955
1946
|
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1947
|
+
task2.cancel('no soup for you');
|
|
1948
|
+
|
|
1949
|
+
return waitForIdle().then(function() {
|
|
1950
|
+
assert.ok(!called);
|
|
1951
|
+
assertFlowHistory('a', 'c');
|
|
1952
|
+
return task2.catch(function(e) {
|
|
1953
|
+
assert.ok(e instanceof promise.CancellationError);
|
|
1954
|
+
assert.equal('no soup for you', e.message);
|
|
1955
|
+
});
|
|
1961
1956
|
});
|
|
1962
1957
|
});
|
|
1963
|
-
});
|
|
1964
1958
|
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
.then(() => seen.push(3))
|
|
1970
|
-
.then(() => seen.push(4))
|
|
1971
|
-
.then(() => seen.push(5));
|
|
1972
|
-
task.cancel(new StubError);
|
|
1959
|
+
it('3', function() {
|
|
1960
|
+
var called = false;
|
|
1961
|
+
var task = scheduleAction('a', () => called = true);
|
|
1962
|
+
task.cancel(new StubError);
|
|
1973
1963
|
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1964
|
+
return waitForIdle().then(function() {
|
|
1965
|
+
assert.ok(!called);
|
|
1966
|
+
assertFlowHistory();
|
|
1967
|
+
return task.catch(function(e) {
|
|
1968
|
+
assert.ok(e instanceof promise.CancellationError);
|
|
1969
|
+
});
|
|
1979
1970
|
});
|
|
1980
1971
|
});
|
|
1981
|
-
});
|
|
1982
1972
|
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1973
|
+
it('4', function() {
|
|
1974
|
+
var seen = [];
|
|
1975
|
+
var task = scheduleAction('a', () => seen.push(1))
|
|
1976
|
+
.then(() => seen.push(2))
|
|
1977
|
+
.then(() => seen.push(3))
|
|
1978
|
+
.then(() => seen.push(4))
|
|
1979
|
+
.then(() => seen.push(5));
|
|
1980
|
+
task.cancel(new StubError);
|
|
1981
|
+
|
|
1982
|
+
return waitForIdle().then(function() {
|
|
1983
|
+
assert.deepEqual([], seen);
|
|
1984
|
+
assertFlowHistory();
|
|
1985
|
+
return task.catch(function(e) {
|
|
1986
|
+
assert.ok(e instanceof promise.CancellationError);
|
|
1987
|
+
});
|
|
1988
|
+
});
|
|
1988
1989
|
});
|
|
1989
|
-
task = scheduleAction('b', () => called = true);
|
|
1990
|
-
schedule('c');
|
|
1991
1990
|
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1991
|
+
it('fromWithinAnExecutingTask', function() {
|
|
1992
|
+
var called = false;
|
|
1993
|
+
var task;
|
|
1994
|
+
scheduleAction('a', function() {
|
|
1995
|
+
task.cancel('no soup for you');
|
|
1996
|
+
});
|
|
1997
|
+
task = scheduleAction('b', () => called = true);
|
|
1998
|
+
schedule('c');
|
|
1999
|
+
|
|
2000
|
+
return waitForIdle().then(function() {
|
|
2001
|
+
assert.ok(!called);
|
|
2002
|
+
assertFlowHistory('a', 'c');
|
|
2003
|
+
return task.catch(function(e) {
|
|
2004
|
+
assert.ok(e instanceof promise.CancellationError);
|
|
2005
|
+
assert.equal('no soup for you', e.message);
|
|
2006
|
+
});
|
|
1998
2007
|
});
|
|
1999
2008
|
});
|
|
2000
2009
|
});
|
|
2001
|
-
});
|
|
2002
2010
|
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2011
|
+
it('testCancellingAPendingTask', function() {
|
|
2012
|
+
var order = [];
|
|
2013
|
+
var unresolved = promise.defer();
|
|
2006
2014
|
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2015
|
+
var innerTask;
|
|
2016
|
+
var outerTask = scheduleAction('a', function() {
|
|
2017
|
+
order.push(1);
|
|
2010
2018
|
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2019
|
+
// Schedule a task that will never finish.
|
|
2020
|
+
innerTask = scheduleAction('a.1', function() {
|
|
2021
|
+
return unresolved.promise;
|
|
2022
|
+
});
|
|
2015
2023
|
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2024
|
+
// Since the outerTask is cancelled below, innerTask should be cancelled
|
|
2025
|
+
// with a DiscardedTaskError, which means its callbacks are silently
|
|
2026
|
+
// dropped - so this should never execute.
|
|
2027
|
+
innerTask.catch(function(e) {
|
|
2028
|
+
order.push(2);
|
|
2029
|
+
});
|
|
2021
2030
|
});
|
|
2022
|
-
|
|
2023
|
-
schedule('b');
|
|
2031
|
+
schedule('b');
|
|
2024
2032
|
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2033
|
+
outerTask.catch(function(e) {
|
|
2034
|
+
order.push(3);
|
|
2035
|
+
assert.ok(e instanceof promise.CancellationError);
|
|
2036
|
+
assert.equal('no soup for you', e.message);
|
|
2037
|
+
});
|
|
2030
2038
|
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2039
|
+
unresolved.promise.catch(function(e) {
|
|
2040
|
+
order.push(4);
|
|
2041
|
+
assert.ok(e instanceof promise.CancellationError);
|
|
2042
|
+
});
|
|
2035
2043
|
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
assert.ok(unresolved.promise.isPending());
|
|
2044
|
+
return timeout(10).then(function() {
|
|
2045
|
+
assert.deepEqual([1], order);
|
|
2039
2046
|
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2047
|
+
outerTask.cancel('no soup for you');
|
|
2048
|
+
return waitForIdle();
|
|
2049
|
+
}).then(function() {
|
|
2050
|
+
assertFlowHistory('a', 'a.1', 'b');
|
|
2051
|
+
assert.deepEqual([1, 3, 4], order);
|
|
2052
|
+
});
|
|
2045
2053
|
});
|
|
2046
|
-
});
|
|
2047
2054
|
|
|
2048
|
-
|
|
2049
|
-
|
|
2055
|
+
it('testCancellingAPendingPromiseCallback', function() {
|
|
2056
|
+
var called = false;
|
|
2050
2057
|
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2058
|
+
var root = promise.fulfilled();
|
|
2059
|
+
root.then(function() {
|
|
2060
|
+
cb2.cancel('no soup for you');
|
|
2061
|
+
});
|
|
2055
2062
|
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2063
|
+
var cb2 = root.then(fail, fail); // These callbacks should never be called.
|
|
2064
|
+
cb2.then(fail, function(e) {
|
|
2065
|
+
called = true;
|
|
2066
|
+
assert.ok(e instanceof promise.CancellationError);
|
|
2067
|
+
assert.equal('no soup for you', e.message);
|
|
2068
|
+
});
|
|
2062
2069
|
|
|
2063
|
-
|
|
2064
|
-
|
|
2070
|
+
return waitForIdle().then(function() {
|
|
2071
|
+
assert.ok(called);
|
|
2072
|
+
});
|
|
2065
2073
|
});
|
|
2066
|
-
});
|
|
2067
2074
|
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2075
|
+
describe('testResetFlow', function() {
|
|
2076
|
+
it('1', function() {
|
|
2077
|
+
var called = 0;
|
|
2078
|
+
var task = flow.execute(() => called++);
|
|
2079
|
+
task.finally(() => called++);
|
|
2073
2080
|
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2081
|
+
return new Promise(function(fulfill) {
|
|
2082
|
+
flow.once('reset', fulfill);
|
|
2083
|
+
flow.reset();
|
|
2077
2084
|
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
return task;
|
|
2085
|
+
}).then(function() {
|
|
2086
|
+
assert.equal(0, called);
|
|
2087
|
+
return task;
|
|
2082
2088
|
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2089
|
+
}).then(fail, function(e) {
|
|
2090
|
+
assert.ok(e instanceof promise.CancellationError);
|
|
2091
|
+
assert.equal('ControlFlow was reset', e.message);
|
|
2092
|
+
});
|
|
2086
2093
|
});
|
|
2087
|
-
});
|
|
2088
2094
|
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2095
|
+
it('2', function() {
|
|
2096
|
+
var called = 0;
|
|
2097
|
+
var task1 = flow.execute(() => called++);
|
|
2098
|
+
task1.finally(() => called++);
|
|
2093
2099
|
|
|
2094
|
-
|
|
2095
|
-
|
|
2100
|
+
var task2 = flow.execute(() => called++);
|
|
2101
|
+
task2.finally(() => called++);
|
|
2096
2102
|
|
|
2097
|
-
|
|
2098
|
-
|
|
2103
|
+
var task3 = flow.execute(() => called++);
|
|
2104
|
+
task3.finally(() => called++);
|
|
2099
2105
|
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2106
|
+
return new Promise(function(fulfill) {
|
|
2107
|
+
flow.once('reset', fulfill);
|
|
2108
|
+
flow.reset();
|
|
2103
2109
|
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
assert.ok(!task2.isPending());
|
|
2108
|
-
assert.ok(!task3.isPending());
|
|
2110
|
+
}).then(function() {
|
|
2111
|
+
assert.equal(0, called);
|
|
2112
|
+
});
|
|
2109
2113
|
});
|
|
2110
2114
|
});
|
|
2111
|
-
});
|
|
2112
2115
|
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
+
describe('testPromiseFulfilledInsideTask', function() {
|
|
2117
|
+
it('1', function() {
|
|
2118
|
+
var order = [];
|
|
2116
2119
|
|
|
2117
|
-
|
|
2118
|
-
|
|
2120
|
+
flow.execute(function() {
|
|
2121
|
+
var d = promise.defer();
|
|
2119
2122
|
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2123
|
+
d.promise.then(() => order.push('a'));
|
|
2124
|
+
d.promise.then(() => order.push('b'));
|
|
2125
|
+
d.promise.then(() => order.push('c'));
|
|
2126
|
+
d.fulfill();
|
|
2124
2127
|
|
|
2125
|
-
|
|
2128
|
+
flow.execute(() => order.push('d'));
|
|
2126
2129
|
|
|
2127
|
-
|
|
2130
|
+
}).then(() => order.push('fin'));
|
|
2128
2131
|
|
|
2129
|
-
|
|
2130
|
-
|
|
2132
|
+
return waitForIdle().then(function() {
|
|
2133
|
+
assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
|
|
2134
|
+
});
|
|
2131
2135
|
});
|
|
2132
|
-
});
|
|
2133
2136
|
|
|
2134
|
-
|
|
2135
|
-
|
|
2137
|
+
it('2', function() {
|
|
2138
|
+
var order = [];
|
|
2136
2139
|
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
+
flow.execute(function() {
|
|
2141
|
+
flow.execute(() => order.push('a'));
|
|
2142
|
+
flow.execute(() => order.push('b'));
|
|
2143
|
+
|
|
2144
|
+
var d = promise.defer();
|
|
2145
|
+
d.promise.then(() => order.push('c'));
|
|
2146
|
+
d.promise.then(() => order.push('d'));
|
|
2147
|
+
d.fulfill();
|
|
2148
|
+
|
|
2149
|
+
flow.execute(() => order.push('e'));
|
|
2150
|
+
|
|
2151
|
+
}).then(() => order.push('fin'));
|
|
2140
2152
|
|
|
2153
|
+
return waitForIdle().then(function() {
|
|
2154
|
+
assert.deepEqual(['a', 'b', 'c', 'd', 'e', 'fin'], order);
|
|
2155
|
+
});
|
|
2156
|
+
});
|
|
2157
|
+
|
|
2158
|
+
it('3', function() {
|
|
2159
|
+
var order = [];
|
|
2141
2160
|
var d = promise.defer();
|
|
2142
2161
|
d.promise.then(() => order.push('c'));
|
|
2143
2162
|
d.promise.then(() => order.push('d'));
|
|
2144
|
-
d.fulfill();
|
|
2145
2163
|
|
|
2146
|
-
flow.execute(()
|
|
2164
|
+
flow.execute(function() {
|
|
2165
|
+
flow.execute(() => order.push('a'));
|
|
2166
|
+
flow.execute(() => order.push('b'));
|
|
2147
2167
|
|
|
2148
|
-
|
|
2168
|
+
d.promise.then(() => order.push('e'));
|
|
2169
|
+
d.fulfill();
|
|
2149
2170
|
|
|
2150
|
-
|
|
2151
|
-
|
|
2171
|
+
flow.execute(() => order.push('f'));
|
|
2172
|
+
|
|
2173
|
+
}).then(() => order.push('fin'));
|
|
2174
|
+
|
|
2175
|
+
return waitForIdle().then(function() {
|
|
2176
|
+
assert.deepEqual(['c', 'd', 'a', 'b', 'e', 'f', 'fin'], order);
|
|
2177
|
+
});
|
|
2152
2178
|
});
|
|
2153
|
-
});
|
|
2154
2179
|
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2180
|
+
it('4', function() {
|
|
2181
|
+
var order = [];
|
|
2182
|
+
var d = promise.defer();
|
|
2183
|
+
d.promise.then(() => order.push('a'));
|
|
2184
|
+
d.promise.then(() => order.push('b'));
|
|
2160
2185
|
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2186
|
+
flow.execute(function() {
|
|
2187
|
+
flow.execute(function() {
|
|
2188
|
+
order.push('c');
|
|
2189
|
+
flow.execute(() => order.push('d'));
|
|
2190
|
+
d.promise.then(() => order.push('e'));
|
|
2191
|
+
});
|
|
2192
|
+
flow.execute(() => order.push('f'));
|
|
2164
2193
|
|
|
2165
|
-
|
|
2166
|
-
|
|
2194
|
+
d.promise.then(() => order.push('g'));
|
|
2195
|
+
d.fulfill();
|
|
2167
2196
|
|
|
2168
|
-
|
|
2197
|
+
flow.execute(() => order.push('h'));
|
|
2169
2198
|
|
|
2170
|
-
|
|
2199
|
+
}).then(() => order.push('fin'));
|
|
2171
2200
|
|
|
2172
|
-
|
|
2173
|
-
|
|
2201
|
+
return waitForIdle().then(function() {
|
|
2202
|
+
assert.deepEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'fin'], order);
|
|
2203
|
+
});
|
|
2174
2204
|
});
|
|
2175
2205
|
});
|
|
2176
2206
|
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
d.promise.then(() => order.push('b'));
|
|
2207
|
+
describe('testSettledPromiseCallbacksInsideATask', function() {
|
|
2208
|
+
it('1', function() {
|
|
2209
|
+
var order = [];
|
|
2210
|
+
var p = promise.fulfilled();
|
|
2182
2211
|
|
|
2183
|
-
flow.execute(function() {
|
|
2184
2212
|
flow.execute(function() {
|
|
2185
|
-
order.push('
|
|
2186
|
-
|
|
2187
|
-
|
|
2213
|
+
flow.execute(() => order.push('a'));
|
|
2214
|
+
p.then(() => order.push('b'));
|
|
2215
|
+
flow.execute(() => order.push('c'));
|
|
2216
|
+
p.then(() => order.push('d'));
|
|
2217
|
+
}).then(() => order.push('fin'));
|
|
2218
|
+
|
|
2219
|
+
return waitForIdle().then(function() {
|
|
2220
|
+
assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
|
|
2188
2221
|
});
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
d.promise.then(() => order.push('g'));
|
|
2192
|
-
d.fulfill();
|
|
2222
|
+
});
|
|
2193
2223
|
|
|
2194
|
-
|
|
2224
|
+
it('2', function() {
|
|
2225
|
+
var order = [];
|
|
2195
2226
|
|
|
2196
|
-
|
|
2227
|
+
flow.execute(function() {
|
|
2228
|
+
flow.execute(() => order.push('a'))
|
|
2229
|
+
.then( () => order.push('c'));
|
|
2230
|
+
flow.execute(() => order.push('b'));
|
|
2231
|
+
}).then(() => order.push('fin'));
|
|
2197
2232
|
|
|
2198
|
-
|
|
2199
|
-
|
|
2233
|
+
return waitForIdle().then(function() {
|
|
2234
|
+
assert.deepEqual(['a', 'c', 'b', 'fin'], order);
|
|
2235
|
+
});
|
|
2200
2236
|
});
|
|
2201
2237
|
});
|
|
2202
|
-
});
|
|
2203
2238
|
|
|
2204
|
-
|
|
2205
|
-
it('1', function() {
|
|
2239
|
+
it('testTasksDoNotWaitForNewlyCreatedPromises', function() {
|
|
2206
2240
|
var order = [];
|
|
2207
|
-
var p = promise.fulfilled();
|
|
2208
2241
|
|
|
2209
2242
|
flow.execute(function() {
|
|
2210
|
-
|
|
2211
|
-
p.then(() => order.push('b'));
|
|
2212
|
-
flow.execute(() => order.push('c'));
|
|
2213
|
-
p.then(() => order.push('d'));
|
|
2214
|
-
}).then(() => order.push('fin'));
|
|
2215
|
-
|
|
2216
|
-
return waitForIdle().then(function() {
|
|
2217
|
-
assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
|
|
2218
|
-
});
|
|
2219
|
-
});
|
|
2243
|
+
var d = promise.defer();
|
|
2220
2244
|
|
|
2221
|
-
|
|
2222
|
-
|
|
2245
|
+
// This is a normal promise, not a task, so the task for this callback is
|
|
2246
|
+
// considered volatile. Volatile tasks should be skipped when they reach
|
|
2247
|
+
// the front of the task queue.
|
|
2248
|
+
d.promise.then(() => order.push('a'));
|
|
2223
2249
|
|
|
2224
|
-
flow.execute(function() {
|
|
2225
|
-
flow.execute(() => order.push('a'))
|
|
2226
|
-
.then( () => order.push('c'));
|
|
2227
2250
|
flow.execute(() => order.push('b'));
|
|
2251
|
+
flow.execute(function() {
|
|
2252
|
+
flow.execute(() => order.push('c'));
|
|
2253
|
+
d.promise.then(() => order.push('d'));
|
|
2254
|
+
d.fulfill();
|
|
2255
|
+
});
|
|
2256
|
+
flow.execute(() => order.push('e'));
|
|
2257
|
+
|
|
2228
2258
|
}).then(() => order.push('fin'));
|
|
2229
2259
|
|
|
2230
2260
|
return waitForIdle().then(function() {
|
|
2231
|
-
assert.deepEqual(['a', 'c', '
|
|
2261
|
+
assert.deepEqual(['b', 'a', 'c', 'd', 'e', 'fin'], order);
|
|
2232
2262
|
});
|
|
2233
2263
|
});
|
|
2234
|
-
});
|
|
2235
|
-
|
|
2236
|
-
it('testTasksDoNotWaitForNewlyCreatedPromises', function() {
|
|
2237
|
-
var order = [];
|
|
2238
2264
|
|
|
2239
|
-
|
|
2240
|
-
var
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
flow.execute(() => order.push('b'));
|
|
2248
|
-
flow.execute(function() {
|
|
2249
|
-
flow.execute(() => order.push('c'));
|
|
2250
|
-
d.promise.then(() => order.push('d'));
|
|
2251
|
-
d.fulfill();
|
|
2265
|
+
it('testCallbackDependenciesDoNotDeadlock', function() {
|
|
2266
|
+
var order = [];
|
|
2267
|
+
var root = promise.defer();
|
|
2268
|
+
var dep = promise.fulfilled().then(function() {
|
|
2269
|
+
order.push('a');
|
|
2270
|
+
return root.promise.then(function() {
|
|
2271
|
+
order.push('b');
|
|
2272
|
+
});
|
|
2252
2273
|
});
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2274
|
+
// This callback depends on |dep|, which depends on another callback
|
|
2275
|
+
// attached to |root| via a chain.
|
|
2276
|
+
root.promise.then(function() {
|
|
2277
|
+
order.push('c');
|
|
2278
|
+
return dep.then(() => order.push('d'));
|
|
2279
|
+
}).then(() => order.push('fin'));
|
|
2256
2280
|
|
|
2257
|
-
|
|
2258
|
-
assert.deepEqual(['b', 'a', 'c', 'd', 'e', 'fin'], order);
|
|
2259
|
-
});
|
|
2260
|
-
});
|
|
2281
|
+
setTimeout(() => root.fulfill(), 20);
|
|
2261
2282
|
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
var root = promise.defer();
|
|
2265
|
-
var dep = promise.fulfilled().then(function() {
|
|
2266
|
-
order.push('a');
|
|
2267
|
-
return root.promise.then(function() {
|
|
2268
|
-
order.push('b');
|
|
2283
|
+
return waitForIdle().then(function() {
|
|
2284
|
+
assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
|
|
2269
2285
|
});
|
|
2270
2286
|
});
|
|
2271
|
-
// This callback depends on |dep|, which depends on another callback
|
|
2272
|
-
// attached to |root| via a chain.
|
|
2273
|
-
root.promise.then(function() {
|
|
2274
|
-
order.push('c');
|
|
2275
|
-
return dep.then(() => order.push('d'));
|
|
2276
|
-
}).then(() => order.push('fin'));
|
|
2277
|
-
|
|
2278
|
-
setTimeout(() => root.fulfill(), 20);
|
|
2279
|
-
|
|
2280
|
-
return waitForIdle().then(function() {
|
|
2281
|
-
assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
|
|
2282
|
-
});
|
|
2283
2287
|
});
|
|
2284
2288
|
});
|