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.
Files changed (77) hide show
  1. package/CHANGES.md +109 -0
  2. package/LICENSE +1 -1
  3. package/README.md +7 -6
  4. package/chrome.js +31 -128
  5. package/edge.js +13 -91
  6. package/example/chrome_android.js +18 -13
  7. package/example/chrome_mobile_emulation.js +19 -15
  8. package/example/google_search.js +11 -11
  9. package/example/google_search_generator.js +23 -18
  10. package/example/google_search_test.js +31 -17
  11. package/example/logging.js +9 -17
  12. package/example/parallel_flows.js +3 -0
  13. package/firefox/binary.js +17 -0
  14. package/firefox/index.js +198 -101
  15. package/firefox/profile.js +24 -3
  16. package/http/util.js +95 -59
  17. package/ie.js +6 -10
  18. package/index.js +636 -2
  19. package/lib/actions.js +18 -10
  20. package/lib/atoms/getAttribute.js +11 -0
  21. package/lib/atoms/isDisplayed.js +106 -0
  22. package/lib/firefox/amd64/libnoblur64.so +0 -0
  23. package/lib/firefox/i386/libnoblur.so +0 -0
  24. package/lib/firefox/webdriver.xpi +0 -0
  25. package/lib/http.js +159 -46
  26. package/lib/logging.js +7 -1
  27. package/lib/promise.js +602 -358
  28. package/lib/proxy.js +28 -0
  29. package/lib/session.js +1 -1
  30. package/lib/test/build.js +26 -28
  31. package/lib/test/data/formPage.html +1 -0
  32. package/lib/test/fileserver.js +12 -10
  33. package/lib/test/httpserver.js +4 -6
  34. package/lib/test/index.js +18 -11
  35. package/lib/test/promise.js +79 -0
  36. package/lib/webdriver.js +587 -479
  37. package/opera.js +12 -88
  38. package/package.json +13 -14
  39. package/phantomjs.js +7 -14
  40. package/remote/index.js +201 -30
  41. package/safari.js +62 -416
  42. package/test/actions_test.js +9 -11
  43. package/test/chrome/options_test.js +8 -8
  44. package/test/chrome/service_test.js +2 -2
  45. package/test/cookie_test.js +57 -57
  46. package/test/element_finding_test.js +201 -185
  47. package/test/execute_script_test.js +108 -111
  48. package/test/fingerprint_test.js +16 -11
  49. package/test/firefox/firefox_test.js +75 -49
  50. package/test/firefox/profile_test.js +1 -3
  51. package/test/http/util_test.js +21 -27
  52. package/test/io_test.js +2 -5
  53. package/test/lib/http_test.js +8 -6
  54. package/test/lib/promise_aplus_test.js +48 -44
  55. package/test/lib/promise_error_test.js +687 -611
  56. package/test/lib/promise_flow_test.js +1810 -1806
  57. package/test/lib/promise_generator_test.js +227 -225
  58. package/test/lib/promise_test.js +864 -835
  59. package/test/lib/until_test.js +1 -1
  60. package/test/lib/webdriver_test.js +520 -424
  61. package/test/logging_test.js +43 -45
  62. package/test/net/portprober_test.js +23 -24
  63. package/test/page_loading_test.js +84 -78
  64. package/test/phantomjs/execute_phantomjs_test.js +11 -25
  65. package/test/proxy_test.js +23 -23
  66. package/test/remote_test.js +22 -22
  67. package/test/safari_test.js +108 -0
  68. package/test/session_test.js +11 -10
  69. package/test/stale_element_test.js +18 -16
  70. package/test/tag_name_test.js +7 -5
  71. package/test/testing/assert_test.js +2 -3
  72. package/test/testing/index_test.js +163 -117
  73. package/test/upload_test.js +13 -13
  74. package/test/window_test.js +94 -70
  75. package/testing/index.js +176 -37
  76. package/builder.js +0 -553
  77. 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
- let flow, flowHistory, messages, uncaughtExceptions;
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
- function onUncaughtException(e) {
60
- uncaughtExceptions.push(e);
61
- }
62
-
63
- function waitForAbort(opt_flow) {
64
- var theFlow = opt_flow || flow;
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
- function timeout(ms) {
87
- return new NativePromise(function(fulfill) {
88
- setTimeout(fulfill, ms);
48
+ uncaughtExceptions = [];
49
+ flow.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
50
+ onUncaughtException);
89
51
  });
90
- }
91
52
 
92
-
93
- function schedule(msg, opt_return) {
94
- return scheduleAction(msg, function() {
95
- return opt_return;
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
- it('aSimpleFunctionWithANonPromiseReturnValue', function() {
173
- schedule('go', 123).then(function(value) {
174
- assert.equal(123, value);
175
- });
176
- return waitForIdle().then(function() {
177
- assertFlowHistory('go');
178
- });
179
- });
62
+ function onUncaughtException(e) {
63
+ uncaughtExceptions.push(e);
64
+ }
180
65
 
181
- it('aSimpleSequence', function() {
182
- schedule('a');
183
- schedule('b');
184
- schedule('c');
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
- it('invokesCallbacksWhenTaskIsDone', function() {
191
- var d = new promise.Deferred();
192
- var called = false;
193
- var done = schedule('a', d.promise).then(function(value) {
194
- called = true;
195
- assert.equal(123, value);
196
- });
197
- return timeout(5).then(function() {
198
- assert.ok(!called);
199
- d.fulfill(123);
200
- return done;
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
- it('executesTasksInAFutureTurnAfterTheyAreScheduled', function() {
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
- function incr() { count++; }
243
-
244
- scheduleAction('', incr);
245
- assert.equal(0, count);
246
- return waitForIdle().then(function() {
247
- assert.equal(1, count);
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
- it('executesOneTaskPerTurnOfTheEventLoop', function() {
252
- var order = [];
253
- function go() {
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
- scheduleAction('', go);
261
- scheduleAction('', go);
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
- it('firstScheduledTaskIsWithinACallback', function() {
268
- promise.fulfilled().then(function() {
193
+ it('aSimpleSequence', function() {
269
194
  schedule('a');
270
195
  schedule('b');
271
196
  schedule('c');
272
- }).then(function() {
273
- assertFlowHistory('a', 'b', 'c');
197
+ return waitForIdle().then(function() {
198
+ assertFlowHistory('a', 'b', 'c');
199
+ });
274
200
  });
275
- return waitForIdle();
276
- });
277
201
 
278
- it('newTasksAddedWhileWaitingOnTaskReturnedPromise1', function() {
279
- scheduleAction('a', function() {
280
- var d = promise.defer();
281
- setTimeout(function() {
282
- schedule('c');
283
- d.fulfill();
284
- }, 10);
285
- return d.promise;
286
- });
287
- schedule('b');
288
- return waitForIdle().then(function() {
289
- assertFlowHistory('a', 'b', 'c');
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
- it('newTasksAddedWhileWaitingOnTaskReturnedPromise2', function() {
294
- scheduleAction('a', function() {
295
- var d = promise.defer();
219
+ it('blocksUntilPromiseReturnedByTaskIsResolved', function() {
220
+ var done = promise.defer();
221
+ schedulePush('a', done.promise);
222
+ schedulePush('b');
296
223
  setTimeout(function() {
297
- schedule('c');
298
- asyncRun(d.fulfill);
299
- }, 10);
300
- return d.promise;
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
- describe('testFraming', function() {
310
- it('callbacksRunInANewFrame', function() {
311
- schedule('a').then(function() {
312
- schedule('c');
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
- schedule('b');
315
- return waitForIdle().then(function() {
316
- assertFlowHistory('a', 'c', 'b');
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
- it('lotsOfNesting', function() {
321
- schedule('a').then(function() {
322
- schedule('c').then(function() {
323
- schedule('e').then(function() {
324
- schedule('g');
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
- schedule('f');
327
- });
328
- schedule('d');
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
- return waitForIdle().then(function() {
333
- assertFlowHistory('a', 'c', 'e', 'g', 'f', 'd', 'b');
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
- it('callbackReturnsPromiseThatDependsOnATask_1', function() {
338
- schedule('a').then(function() {
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 promise.delayed(5).then(function() {
341
- return schedule('c');
300
+ return waitForIdle().then(function() {
301
+ assertFlowHistory('a', 'b', 'c');
342
302
  });
343
303
  });
344
- schedule('d');
345
304
 
346
- return waitForIdle().then(function() {
347
- assertFlowHistory('a', 'b', 'c', 'd');
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
- it('callbackReturnsPromiseThatDependsOnATask_2', function() {
352
- schedule('a').then(function() {
321
+ describe('testFraming', function() {
322
+ it('callbacksRunInANewFrame', function() {
323
+ schedule('a').then(function() {
324
+ schedule('c');
325
+ });
353
326
  schedule('b');
354
- return promise.delayed(5).
355
- then(function() { return promise.delayed(5) }).
356
- then(function() { return promise.delayed(5) }).
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
- it('eachCallbackWaitsForAllScheduledTasksToComplete', function() {
368
- schedule('a').
369
- then(function() {
370
- schedule('b');
371
- schedule('c');
372
- }).
373
- then(function() {
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
- schedule('e');
340
+ schedule('d');
341
+ });
342
+ schedule('b');
377
343
 
378
- return waitForIdle().then(function() {
379
- assertFlowHistory('a', 'b', 'c', 'd', 'e');
344
+ return waitForIdle().then(function() {
345
+ assertFlowHistory('a', 'c', 'e', 'g', 'f', 'd', 'b');
346
+ });
380
347
  });
381
- });
382
348
 
383
- it('eachCallbackWaitsForReturnTasksToComplete', function() {
384
- schedule('a').
385
- then(function() {
386
- schedule('b');
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
- schedule('e');
355
+ });
356
+ schedule('d');
393
357
 
394
- return waitForIdle().then(function() {
395
- assertFlowHistory('a', 'b', 'c', 'd', 'e');
358
+ return waitForIdle().then(function() {
359
+ assertFlowHistory('a', 'b', 'c', 'd');
360
+ });
396
361
  });
397
- });
398
362
 
399
- it('callbacksOnAResolvedPromiseInsertIntoTheCurrentFlow', function() {
400
- promise.fulfilled().then(function() {
401
- schedule('b');
402
- });
403
- schedule('a');
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
- return waitForIdle().then(function() {
406
- assertFlowHistory('b', 'a');
374
+ return waitForIdle().then(function() {
375
+ assertFlowHistory('a', 'b', 'c', 'd');
376
+ });
407
377
  });
408
- });
409
378
 
410
- it('callbacksInterruptTheFlowWhenPromiseIsResolved', function() {
411
- schedule('a').then(function() {
412
- schedule('c');
413
- });
414
- schedule('b');
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
- return waitForIdle().then(function() {
417
- assertFlowHistory('a', 'c', 'b');
390
+ return waitForIdle().then(function() {
391
+ assertFlowHistory('a', 'b', 'c', 'd', 'e');
392
+ });
418
393
  });
419
- });
420
394
 
421
- it('allCallbacksInAFrameAreScheduledWhenPromiseIsResolved', function() {
422
- var a = schedule('a');
423
- a.then(function() { schedule('b'); });
424
- schedule('c');
425
- a.then(function() { schedule('d'); });
426
- schedule('e');
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
- return waitForIdle().then(function() {
429
- assertFlowHistory('a', 'b', 'c', 'd', 'e');
406
+ return waitForIdle().then(function() {
407
+ assertFlowHistory('a', 'b', 'c', 'd', 'e');
408
+ });
430
409
  });
431
- });
432
410
 
433
- it('tasksScheduledInInActiveFrameDoNotGetPrecedence', function() {
434
- var d = promise.fulfilled();
435
- schedule('a');
436
- schedule('b');
437
- d.then(function() { schedule('c'); });
411
+ it('callbacksOnAResolvedPromiseInsertIntoTheCurrentFlow', function() {
412
+ promise.fulfilled().then(function() {
413
+ schedule('b');
414
+ });
415
+ schedule('a');
438
416
 
439
- return waitForIdle().then(function() {
440
- assertFlowHistory('a', 'b', 'c');
417
+ return waitForIdle().then(function() {
418
+ assertFlowHistory('b', 'a');
419
+ });
441
420
  });
442
- });
443
421
 
444
- it('tasksScheduledInAFrameGetPrecedence_1', function() {
445
- var a = schedule('a');
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
- var e = schedule('e');
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
- return waitForIdle().then(function() {
464
- assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j');
428
+ return waitForIdle().then(function() {
429
+ assertFlowHistory('a', 'c', 'b');
430
+ });
465
431
  });
466
- });
467
- });
468
432
 
469
- describe('testErrorHandling', function() {
470
- it('thrownErrorsArePassedToTaskErrback', function() {
471
- scheduleAction('function that throws', throwStubError).
472
- then(fail, assertIsStubError);
473
- return waitForIdle();
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
- it('thrownErrorsPropagateThroughPromiseChain', function() {
477
- scheduleAction('function that throws', throwStubError).
478
- then(fail).
479
- then(fail, assertIsStubError);
480
- return waitForIdle();
481
- });
440
+ return waitForIdle().then(function() {
441
+ assertFlowHistory('a', 'b', 'c', 'd', 'e');
442
+ });
443
+ });
482
444
 
483
- it('catchesErrorsFromFailedTasksInAFrame', function() {
484
- schedule('a').then(function() {
445
+ it('tasksScheduledInInActiveFrameDoNotGetPrecedence', function() {
446
+ var d = promise.fulfilled();
447
+ schedule('a');
485
448
  schedule('b');
486
- scheduleAction('function that throws', throwStubError);
487
- }).
488
- then(fail, assertIsStubError);
489
- return waitForIdle();
490
- });
449
+ d.then(function() { schedule('c'); });
491
450
 
492
- it('abortsIfOnlyTaskReturnsAnUnhandledRejection', function() {
493
- scheduleAction('function that returns rejected promise', function() {
494
- return promise.rejected(new StubError);
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
- it('abortsSequenceIfATaskFails', function() {
510
- schedule('a');
511
- schedule('b');
512
- scheduleAction('c', throwStubError);
513
- schedule('d'); // Should never execute.
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
- it('abortsFromUnhandledFramedTaskFailures_1', function() {
523
- schedule('outer task').then(function() {
524
- scheduleAction('inner task', throwStubError);
525
- });
526
- schedule('this should not run');
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
- return waitForAbort().
544
- then(assertIsStubError).
545
- then(function() {
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
- it('canCatchErrorsFromNestedTasks', function() {
579
- var errback = sinon.spy();
580
- schedule('a').
581
- then(function() {
582
- return scheduleAction('b', throwStubError);
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
- it('aTaskWithAnUnhandledPromiseRejection', function() {
610
- schedule('a');
611
- scheduleAction('sub-tasks', function() {
612
- promise.rejected(new StubError);
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
- return waitForAbort().
617
- then(assertIsStubError).
618
- then(function() {
619
- assertFlowHistory('a', 'sub-tasks');
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
- return waitForAbort().
704
- then(assertIsStubError).
705
- then(assertingMessages('foo', 'baz'));
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
- it('taskDependsOnImmediatelyFulfilledPromise', function() {
746
- scheduleAction('a', function() {
747
- return promise.fulfilled();
748
- }).then(function() {
749
- schedule('b');
750
- });
751
- schedule('c');
752
- return waitForIdle().then(function() {
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
- it('taskDependsOnPreviouslyFulfilledPromise', function() {
758
- var aPromise = promise.fulfilled(123);
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
- it('taskDependsOnAsyncPromise', function() {
772
- scheduleAction('a', function() {
773
- return promise.delayed(25);
774
- }).then(function() {
775
- schedule('b');
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
- schedule('c');
778
- return waitForIdle().then(function() {
779
- assertFlowHistory('a', 'b', 'c');
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
- it('promiseChainedToTaskInterruptFlow', function() {
784
- schedule('a').then(function() {
785
- return promise.fulfilled();
786
- }).then(function() {
787
- return promise.fulfilled();
788
- }).then(function() {
789
- schedule('b');
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
- schedule('c');
792
- return waitForIdle().then(function() {
793
- assertFlowHistory('a', 'b', 'c');
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
- it('nestedTaskCallbacksInterruptFlowWhenResolved', function() {
798
- schedule('a').then(function() {
799
- schedule('b').then(function() {
800
- schedule('c');
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
- schedule('d');
804
- return waitForIdle().then(function() {
805
- assertFlowHistory('a', 'b', 'c', 'd');
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
- describe('testDelayedNesting', function() {
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
- it('1', function() {
813
- var a = schedule('a');
814
- schedule('b').then(function() {
815
- a.then(function() { schedule('c'); });
816
- schedule('d');
628
+ return waitForAbort().
629
+ then(assertIsStubError).
630
+ then(function() {
631
+ assertFlowHistory('a', 'sub-tasks');
632
+ });
817
633
  });
818
- schedule('e');
819
634
 
820
- return waitForIdle().then(function() {
821
- assertFlowHistory('a', 'b', 'c', 'd', 'e');
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
- it('2', function() {
826
- var a = schedule('a');
827
- schedule('b').then(function() {
828
- a.then(function() { schedule('c'); });
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
- a.then(function() { schedule('e'); });
657
+
658
+ return waitForIdle().
659
+ then(pair.assertErrback).
660
+ then(function() {
661
+ assertFlowHistory('a', 'd');
662
+ });
831
663
  });
832
- schedule('f');
833
664
 
834
- return waitForIdle().then(function() {
835
- assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f');
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
- it('3', function() {
840
- var a = schedule('a');
841
- schedule('b').then(function() {
842
- a.then(function() { schedule('c'); });
843
- a.then(function() { schedule('d'); });
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
- schedule('e');
744
+ });
846
745
 
847
- return waitForIdle().then(function() {
848
- assertFlowHistory('a', 'b', 'c', 'd', 'e');
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
- it('4', function() {
853
- var a = schedule('a');
854
- schedule('b').then(function() {
855
- a.then(function() { schedule('c'); }).then(function() {
856
- schedule('d');
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
- return waitForIdle().then(function() {
863
- assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f');
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
- it('5', function() {
868
- var a = schedule('a');
869
- schedule('b').then(function() {
870
- var c;
871
- a.then(function() { c = schedule('c'); }).then(function() {
872
- schedule('d');
873
- a.then(function() { schedule('e'); });
874
- c.then(function() { schedule('f'); });
875
- schedule('g');
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
- return waitForIdle().then(function() {
882
- assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i');
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
- describe('testWaiting', function() {
888
- it('onAConditionThatIsAlwaysTrue', function() {
889
- scheduleWait(function() { return true;}, 0, 'waiting on true');
890
- return waitForIdle().then(function() {
891
- assertFlowHistory('0: waiting on true');
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
- it('aSimpleCountingCondition', function() {
896
- var count = 0;
897
- scheduleWait(function() {
898
- return ++count == 3;
899
- }, 100, 'counting to 3');
822
+ describe('testDelayedNesting', function() {
900
823
 
901
- return waitForIdle().then(function() {
902
- assert.equal(3, count);
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
- it('aConditionThatReturnsAPromise', function() {
907
- var d = new promise.Deferred();
908
- var count = 0;
832
+ return waitForIdle().then(function() {
833
+ assertFlowHistory('a', 'b', 'c', 'd', 'e');
834
+ });
835
+ });
909
836
 
910
- scheduleWait(function() {
911
- count += 1;
912
- return d.promise;
913
- }, 0, 'waiting for promise');
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
- return timeout(50).then(function() {
916
- assert.equal(1, count);
917
- d.fulfill(123);
918
- return waitForIdle();
846
+ return waitForIdle().then(function() {
847
+ assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f');
848
+ });
919
849
  });
920
- });
921
850
 
922
- it('aConditionThatReturnsAPromise_2', function() {
923
- var count = 0;
924
- scheduleWait(function() {
925
- return promise.fulfilled(++count == 3);
926
- }, 100, 'waiting for promise');
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
- return waitForIdle().then(function() {
929
- assert.equal(3, count);
859
+ return waitForIdle().then(function() {
860
+ assertFlowHistory('a', 'b', 'c', 'd', 'e');
861
+ });
930
862
  });
931
- });
932
863
 
933
- it('aConditionThatReturnsATaskResult', function() {
934
- var count = 0;
935
- scheduleWait(function() {
936
- return scheduleAction('increment count', function() {
937
- return ++count == 3;
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
- }, 100, 'counting to 3');
940
- schedule('post wait');
872
+ schedule('f');
941
873
 
942
- return waitForIdle().then(function() {
943
- assert.equal(3, count);
944
- assertFlowHistory(
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
- it('conditionContainsASubtask', function() {
953
- var count = 0;
954
- scheduleWait(function() {
955
- schedule('sub task');
956
- return ++count == 3;
957
- }, 100, 'counting to 3');
958
- schedule('post wait');
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
- return waitForIdle().then(function() {
961
- assert.equal(3, count);
962
- assertFlowHistory(
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
- it('cancelsWaitIfScheduledTaskFails', function() {
971
- var pair = callbackPair(null, assertIsStubError);
972
- scheduleWait(function() {
973
- scheduleAction('boom', throwStubError);
974
- schedule('this should not run');
975
- return true;
976
- }, 100, 'waiting to go boom').then(pair.callback, pair.errback);
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
- return waitForIdle().
980
- then(pair.assertErrback).
981
- then(function() {
982
- assertFlowHistory(
983
- '0: waiting to go boom', 'boom',
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
- it('failsIfConditionThrows', function() {
989
- var callbacks = callbackPair(null, assertIsStubError);
990
- scheduleWait(throwStubError, 0, 'goes boom').
991
- then(callbacks.callback, callbacks.errback);
992
- schedule('post wait');
913
+ return waitForIdle().then(function() {
914
+ assert.equal(3, count);
915
+ });
916
+ });
993
917
 
994
- return waitForIdle().
995
- then(callbacks.assertErrback).
996
- then(function() {
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
- it('failsIfConditionReturnsARejectedPromise', function() {
1002
- var callbacks = callbackPair(null, assertIsStubError);
1003
- scheduleWait(function() {
1004
- return promise.rejected(new StubError);
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
- return waitForIdle().
1009
- then(callbacks.assertErrback).
1010
- then(function() {
1011
- assertFlowHistory('0: goes boom', 'post wait');
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
- it('failsIfConditionHasUnhandledRejection', function() {
1016
- var callbacks = callbackPair(null, assertIsStubError);
1017
- scheduleWait(function() {
1018
- promise.controlFlow().execute(throwStubError);
1019
- }, 0, 'goes boom').then(callbacks.callback, callbacks.errback);
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
- return waitForIdle().
1023
- then(callbacks.assertErrback).
1024
- then(function() {
1025
- assertFlowHistory('0: goes boom', 'post wait');
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
- it('failsIfConditionHasAFailedSubtask', function() {
1030
- var callbacks = callbackPair(null, assertIsStubError);
1031
- var count = 0;
1032
- scheduleWait(function() {
1033
- scheduleAction('maybe throw', function() {
1034
- if (++count == 2) {
1035
- throw new StubError;
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
- }, 100, 'waiting').then(callbacks.callback, callbacks.errback);
1039
- schedule('post wait');
980
+ });
1040
981
 
1041
- return waitForIdle().then(function() {
1042
- assert.equal(2, count);
1043
- assertFlowHistory(
1044
- '0: waiting', 'maybe throw',
1045
- '1: waiting', 'maybe throw',
1046
- 'post wait');
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
- it('pollingLoopWaitsForAllScheduledTasksInCondition', function() {
1051
- var count = 0;
1052
- scheduleWait(function() {
1053
- scheduleAction('increment count', function() { ++count; });
1054
- return count >= 3;
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
- return waitForIdle().then(function() {
1059
- assert.equal(4, count);
1060
- assertFlowHistory(
1061
- '0: counting to 3', 'increment count',
1062
- '1: counting to 3', 'increment count',
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
- it('waitsForeverOnAZeroTimeout', function() {
1070
- var done = false;
1071
- setTimeout(function() {
1072
- done = true;
1073
- }, 150);
1074
- var waitResult = scheduleWait(function() {
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
- return timeout(75).then(function() {
1079
- assert.ok(!done);
1080
- return timeout(100);
1081
- }).then(function() {
1082
- assert.ok(done);
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
- it('waitsForeverIfTimeoutOmitted', function() {
1088
- var done = false;
1089
- setTimeout(function() {
1090
- done = true;
1091
- }, 150);
1092
- var waitResult = scheduleWait(function() {
1093
- return done;
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
- return timeout(75).then(function() {
1097
- assert.ok(!done);
1098
- return timeout(100);
1099
- }).then(function() {
1100
- assert.ok(done);
1101
- return waitResult;
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
- it('timesOut_nonZeroTimeout', function() {
1106
- var count = 0;
1107
- scheduleWait(function() {
1108
- count += 1;
1109
- var ms = count === 2 ? 65 : 5;
1110
- return promise.delayed(ms).then(function() {
1111
- return false;
1112
- });
1113
- }, 60, 'counting to 3');
1114
- return waitForAbort().then(function(e) {
1115
- switch (count) {
1116
- case 1:
1117
- assertFlowHistory('0: counting to 3');
1118
- break;
1119
- case 2:
1120
- assertFlowHistory('0: counting to 3', '1: counting to 3');
1121
- break;
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
- it('shouldFailIfConditionReturnsARejectedPromise', function() {
1131
- scheduleWait(function() {
1132
- return promise.rejected(new StubError);
1133
- }, 100, 'returns rejected promise on first pass');
1134
- return waitForAbort().then(assertIsStubError);
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
- it('scheduleWithIntermittentWaits', function() {
1138
- schedule('a');
1139
- scheduleWait(function() { return true; }, 0, 'wait 1');
1140
- schedule('b');
1141
- scheduleWait(function() { return true; }, 0, 'wait 2');
1142
- schedule('c');
1143
- scheduleWait(function() { return true; }, 0, 'wait 3');
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
- return waitForIdle().then(function() {
1146
- assertFlowHistory('a', '0: wait 1', 'b', '0: wait 2', 'c', '0: wait 3');
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
- it('scheduleWithIntermittentAndNestedWaits', function() {
1151
- schedule('a');
1152
- scheduleWait(function() { return true; }, 0, 'wait 1').
1153
- then(function() {
1154
- schedule('d');
1155
- scheduleWait(function() { return true; }, 0, 'wait 2');
1156
- schedule('e');
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
- schedule('b');
1159
- scheduleWait(function() { return true; }, 0, 'wait 3');
1160
- schedule('c');
1161
- scheduleWait(function() { return true; }, 0, 'wait 4');
1162
-
1163
- return waitForIdle().then(function() {
1164
- assertFlowHistory(
1165
- 'a', '0: wait 1', 'd', '0: wait 2', 'e', 'b', '0: wait 3', 'c',
1166
- '0: wait 4');
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
- it('requiresConditionToBeAPromiseOrFunction', function() {
1171
- assert.throws(function() {
1172
- flow.wait(1234, 0);
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
- it('promiseThatDoesNotResolveBeforeTimeout', function() {
1180
- var d = promise.defer();
1181
- flow.wait(d.promise, 5).then(fail, function(e) {
1182
- assert.ok(
1183
- /Timed out waiting for promise to resolve after \d+ms/
1184
- .test(e.message),
1185
- 'unexpected error message: ' + e.message);
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
- return waitForIdle().then(function() {
1188
- assert.ok('Promise should not be cancelled', d.promise.isPending());
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
- it('unboundedWaitOnPromiseResolution', function() {
1193
- var messages = [];
1194
- var d = promise.defer();
1195
- var waitResult = flow.wait(d.promise).then(function(value) {
1196
- messages.push('b');
1197
- assert.equal(1234, value);
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
- setTimeout(function() {
1200
- messages.push('a');
1201
- }, 5);
1202
-
1203
- timeout(10).then(function() {
1204
- assert.deepEqual(['a'], messages);
1205
- assert.ok(waitResult.isPending());
1206
- d.fulfill(1234);
1207
- return waitResult;
1208
- }).then(function() {
1209
- assert.deepEqual(['a', 'b'], messages);
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
- return waitForIdle();
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
- describe('testSubtasks', function() {
1217
- it('(base case)', function() {
1218
- schedule('a');
1219
- scheduleAction('sub-tasks', function() {
1220
- schedule('c');
1221
- schedule('d');
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
- return waitForIdle().then(function() {
1226
- assertFlowHistory('a', 'sub-tasks', 'c', 'd', 'b');
1223
+ return waitForIdle();
1227
1224
  });
1228
1225
  });
1229
1226
 
1230
- it('nesting', function() {
1231
- schedule('a');
1232
- scheduleAction('sub-tasks', function() {
1233
- schedule('b');
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('e');
1239
- });
1240
- schedule('f');
1234
+ schedule('b');
1241
1235
 
1242
- return waitForIdle().then(function() {
1243
- assertFlowHistory(
1244
- 'a', 'sub-tasks', 'b', 'sub-sub-tasks', 'c', 'd', 'e', 'f');
1236
+ return waitForIdle().then(function() {
1237
+ assertFlowHistory('a', 'sub-tasks', 'c', 'd', 'b');
1238
+ });
1245
1239
  });
1246
- });
1247
1240
 
1248
- it('taskReturnsSubTaskResult_1', function() {
1249
- schedule('a');
1250
- scheduleAction('sub-tasks', function() {
1251
- return schedule('c');
1252
- });
1253
- schedule('b');
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
- return waitForIdle().then(function() {
1256
- assertFlowHistory('a', 'sub-tasks', 'c', 'b');
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
- it('taskReturnsSubTaskResult_2', function() {
1261
- let pair = callbackPair((value) => assert.equal(123, value));
1262
- schedule('a');
1263
- schedule('sub-tasks', promise.fulfilled(123)).then(pair.callback);
1264
- schedule('b');
1259
+ it('taskReturnsSubTaskResult_1', function() {
1260
+ schedule('a');
1261
+ scheduleAction('sub-tasks', function() {
1262
+ return schedule('c');
1263
+ });
1264
+ schedule('b');
1265
1265
 
1266
- return waitForIdle().then(function() {
1267
- assertFlowHistory('a', 'sub-tasks','b');
1268
- pair.assertCallback();
1266
+ return waitForIdle().then(function() {
1267
+ assertFlowHistory('a', 'sub-tasks', 'c', 'b');
1268
+ });
1269
1269
  });
1270
- });
1271
1270
 
1272
- it('taskReturnsPromiseThatDependsOnSubtask_1', function() {
1273
- scheduleAction('a', function() {
1274
- return promise.delayed(10).then(function() {
1275
- schedule('b');
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
- it('taskReturnsPromiseThatDependsOnSubtask_2', function() {
1285
- scheduleAction('a', function() {
1286
- return promise.fulfilled().then(function() {
1287
- schedule('b');
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
- it('taskReturnsPromiseThatDependsOnSubtask_3', function() {
1297
- scheduleAction('a', function() {
1298
- return promise.delayed(10).then(function() {
1299
- return schedule('b');
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
- it('taskReturnsPromiseThatDependsOnSubtask_4', function() {
1309
- scheduleAction('a', function() {
1310
- return promise.delayed(5).then(function() {
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
- schedule('c');
1317
- return waitForIdle().then(function() {
1318
- assertFlowHistory('a', 'b', 'c');
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
- it('taskReturnsPromiseThatDependsOnSubtask_5', function() {
1323
- scheduleAction('a', function() {
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 schedule('b');
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
- it('taskReturnsPromiseThatDependsOnSubtask_6', function() {
1341
- scheduleAction('a', function() {
1342
- return promise.delayed(5).
1343
- then(function() { return promise.delayed(5) }).
1344
- then(function() { return promise.delayed(5) }).
1345
- then(function() { return promise.delayed(5) }).
1346
- then(function() { return schedule('b'); });
1347
- });
1348
- schedule('c');
1349
- return waitForIdle().then(function() {
1350
- assertFlowHistory('a', 'b', 'c');
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
- it('subTaskFails_1', function() {
1355
- schedule('a');
1356
- scheduleAction('sub-tasks', function() {
1357
- scheduleAction('sub-task that fails', throwStubError);
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
- return waitForAbort().
1362
- then(assertIsStubError).
1363
- then(function() {
1364
- assertFlowHistory('a', 'sub-tasks', 'sub-task that fails');
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
- it('subTaskFails_2', function() {
1369
- schedule('a');
1370
- scheduleAction('sub-tasks', function() {
1371
- return promise.rejected(new StubError);
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
- it('subTaskFails_3', function() {
1383
- var callbacks = callbackPair(null, assertIsStubError);
1393
+ it('subTaskFails_3', function() {
1394
+ var callbacks = callbackPair(null, assertIsStubError);
1384
1395
 
1385
- schedule('a');
1386
- scheduleAction('sub-tasks', function() {
1387
- return promise.rejected(new StubError);
1388
- }).then(callbacks.callback, callbacks.errback);
1389
- schedule('b');
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
- return waitForIdle().
1392
- then(function() {
1393
- assertFlowHistory('a', 'sub-tasks', 'b');
1394
- callbacks.assertErrback();
1395
- });
1402
+ return waitForIdle().
1403
+ then(function() {
1404
+ assertFlowHistory('a', 'sub-tasks', 'b');
1405
+ callbacks.assertErrback();
1406
+ });
1407
+ });
1396
1408
  });
1397
- });
1398
1409
 
1399
- describe('testEventLoopWaitsOnPendingPromiseRejections', function() {
1400
- it('oneRejection', function() {
1401
- var d = new promise.Deferred;
1402
- scheduleAction('one', function() {
1403
- return d.promise;
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
- return timeout(50).then(function() {
1408
- assertFlowHistory('one');
1409
- d.reject(new StubError);
1410
- return waitForAbort();
1411
- }).
1412
- then(assertIsStubError).
1413
- then(function() {
1414
- assertFlowHistory('one');
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
- it('multipleRejections', function() {
1419
- var once = Error('once');
1420
- var twice = Error('twice');
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
- scheduleAction('one', function() {
1423
- promise.rejected(once);
1424
- promise.rejected(twice);
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
- flow.removeAllListeners(
1429
- promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
1430
- return new NativePromise(function(fulfill, reject) {
1431
- setTimeout(function() {
1432
- reject(Error('Should have reported the two errors by now'));
1433
- }, 50);
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
- describe('testCancelsPromiseReturnedByCallbackIfFrameFails', function() {
1449
- it('promiseCallback', function() {
1450
- var chainPair = callbackPair(null, assertIsStubError);
1451
- var deferredPair = callbackPair(null, function(e) {
1452
- assert.equal('CancellationError: StubError', e.toString(),
1453
- 'callback result should be cancelled');
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
- var d = new promise.Deferred();
1457
- d.promise.then(deferredPair.callback, deferredPair.errback);
1458
-
1459
- promise.fulfilled().
1510
+ it('testMaintainsOrderInCallbacksWhenATaskReturnsAPromise', function() {
1511
+ schedule('__start__', promise.fulfilled()).
1460
1512
  then(function() {
1461
- scheduleAction('boom', throwStubError);
1462
- schedule('this should not run');
1463
- return d.promise;
1513
+ messages.push('a');
1514
+ schedulePush('b');
1515
+ messages.push('c');
1464
1516
  }).
1465
- then(chainPair.callback, chainPair.errback);
1517
+ then(function() {
1518
+ messages.push('d');
1519
+ });
1520
+ schedulePush('e');
1466
1521
 
1467
1522
  return waitForIdle().then(function() {
1468
- assertFlowHistory('boom');
1469
- chainPair.assertErrback('chain errback not invoked');
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('taskCallback', function() {
1475
- var chainPair = callbackPair(null, assertIsStubError);
1476
- var deferredPair = callbackPair(null, function(e) {
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
- var d = new promise.Deferred();
1482
- d.promise.then(deferredPair.callback, deferredPair.errback);
1532
+ promise.createFlow(function(flow) {
1533
+ assertFlowIs(flow);
1534
+ order.push(0);
1483
1535
 
1484
- schedule('a').
1485
- then(function() {
1486
- scheduleAction('boom', throwStubError);
1487
- schedule('this should not run');
1488
- return d.promise;
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
- assertFlowHistory('a', 'boom');
1494
- chainPair.assertErrback('chain errback not invoked');
1495
- deferredPair.assertErrback('deferred errback not invoked');
1543
+ assertFlowIs(defaultFlow);
1544
+ assert.deepEqual([0, 1], order);
1496
1545
  });
1497
1546
  });
1498
- });
1499
1547
 
1500
- it('testMaintainsOrderInCallbacksWhenATaskReturnsAPromise', function() {
1501
- schedule('__start__', promise.fulfilled()).
1502
- then(function() {
1503
- messages.push('a');
1504
- schedulePush('b');
1505
- messages.push('c');
1506
- }).
1507
- then(function() {
1508
- messages.push('d');
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
- schedulePush('e');
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
- promise.createFlow(function(flow) {
1523
- assertFlowIs(flow);
1524
- order.push(0);
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
- return waitForIdle().then(function() {
1533
- assertFlowIs(defaultFlow);
1534
- assert.deepEqual([0, 1], order);
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
- it('testDeferredFactoriesCreateForActiveFlow_defaultFlow', function() {
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
- return waitForIdle();
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
- it('testDeferredFactoriesCreateForActiveFlow_newFlow', function() {
1569
- var e = Error();
1570
- var newFlow = new promise.ControlFlow;
1571
- newFlow.execute(function() {
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
- promise.rejected(e).then(null, function(err) {
1577
- assert.equal(e, err);
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
- let d = promise.defer();
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
- return waitForIdle(newFlow);
1591
- });
1592
-
1593
- it('testFlowsSynchronizeWithThemselvesNotEachOther', function() {
1594
- var defaultFlow = promise.controlFlow();
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
- promise.createFlow(function() {
1600
- schedulePush('c', 'c');
1601
- schedulePush('d', 'd');
1602
- });
1609
+ promise.createFlow(function(flow2) {
1610
+ assertFlowIs(flow2);
1611
+ schedulePush('c', 'c');
1612
+ schedulePush('d', 'd');
1613
+ });
1603
1614
 
1604
- return waitForIdle().then(function() {
1605
- assertMessages('a', 'c', 'd', 'b');
1615
+ return waitForIdle().then(function() {
1616
+ assertMessages('a', 'c', 'd', 'b');
1617
+ });
1606
1618
  });
1607
- });
1608
1619
 
1609
- it('testUnhandledErrorsAreReportedToTheOwningFlow', function() {
1610
- var error1 = Error('e1');
1611
- var error2 = Error('e2');
1620
+ it('testUnhandledErrorsAreReportedToTheOwningFlow', function() {
1621
+ var error1 = Error('e1');
1622
+ var error2 = Error('e2');
1612
1623
 
1613
- var defaultFlow = promise.controlFlow();
1614
- defaultFlow.removeAllListeners('uncaughtException');
1624
+ var defaultFlow = promise.controlFlow();
1625
+ defaultFlow.removeAllListeners('uncaughtException');
1615
1626
 
1616
- var flow1Error = NativePromise.defer();
1617
- flow1Error.promise.then(function(value) {
1618
- assert.equal(error2, value);
1619
- });
1627
+ var flow1Error = defer();
1628
+ flow1Error.promise.then(function(value) {
1629
+ assert.equal(error2, value);
1630
+ });
1620
1631
 
1621
- var flow2Error = NativePromise.defer();
1622
- flow2Error.promise.then(function(value) {
1623
- assert.equal(error1, value);
1624
- });
1632
+ var flow2Error = defer();
1633
+ flow2Error.promise.then(function(value) {
1634
+ assert.equal(error1, value);
1635
+ });
1625
1636
 
1626
- promise.createFlow(function(flow) {
1627
- flow.once('uncaughtException', flow2Error.resolve);
1628
- promise.rejected(error1);
1637
+ promise.createFlow(function(flow) {
1638
+ flow.once('uncaughtException', flow2Error.resolve);
1639
+ promise.rejected(error1);
1629
1640
 
1630
- defaultFlow.once('uncaughtException', flow1Error.resolve);
1631
- defaultFlow.execute(function() {
1632
- promise.rejected(error2);
1641
+ defaultFlow.once('uncaughtException', flow1Error.resolve);
1642
+ defaultFlow.execute(function() {
1643
+ promise.rejected(error2);
1644
+ });
1633
1645
  });
1634
- });
1635
1646
 
1636
- return NativePromise.all([flow1Error.promise, flow2Error.promise]);
1637
- });
1647
+ return NativePromise.all([flow1Error.promise, flow2Error.promise]);
1648
+ });
1638
1649
 
1639
- it('testCanSynchronizeFlowsByReturningPromiseFromOneToAnother', function() {
1640
- var flow1 = new promise.ControlFlow;
1641
- var flow1Done = NativePromise.defer();
1642
- flow1.once('idle', flow1Done.resolve);
1643
- flow1.once('uncaughtException', flow1Done.reject);
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
- var flow2 = new promise.ControlFlow;
1646
- var flow2Done = NativePromise.defer();
1647
- flow2.once('idle', flow2Done.resolve);
1648
- flow2.once('uncaughtException', flow2Done.reject);
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
- flow1.execute(function() {
1651
- schedulePush('a', 'a');
1652
- return promise.delayed(25);
1653
- }, 'start flow 1');
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
- return flow1.execute(function() {
1660
- schedulePush('d', 'd');
1661
- }, 'flow 1 task');
1662
- }, 'inject flow1 result into flow2');
1663
- schedulePush('e', 'e');
1664
- }, 'start flow 2');
1665
-
1666
- return NativePromise.all([flow1Done.promise, flow2Done.promise]).
1667
- then(function() {
1668
- assertMessages('a', 'b', 'c', 'd', 'e');
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
- it('testFramesWaitToCompleteForPendingRejections', function() {
1673
- return new NativePromise(function(fulfill, reject) {
1683
+ it('testFramesWaitToCompleteForPendingRejections', function() {
1684
+ return new NativePromise(function(fulfill, reject) {
1674
1685
 
1675
- promise.controlFlow().execute(function() {
1676
- promise.rejected(new StubError);
1677
- }).then(fulfill, reject);
1686
+ promise.controlFlow().execute(function() {
1687
+ promise.rejected(new StubError);
1688
+ }).then(fulfill, reject);
1678
1689
 
1679
- }).
1680
- then(() => fail('expected to fail'), assertIsStubError);
1681
- });
1690
+ }).
1691
+ then(() => fail('expected to fail'), assertIsStubError);
1692
+ });
1682
1693
 
1683
- it('testSynchronizeErrorsPropagateToOuterFlow', function() {
1684
- var outerFlow = new promise.ControlFlow;
1685
- var innerFlow = new promise.ControlFlow;
1694
+ it('testSynchronizeErrorsPropagateToOuterFlow', function() {
1695
+ var outerFlow = new promise.ControlFlow;
1696
+ var innerFlow = new promise.ControlFlow;
1686
1697
 
1687
- var block = NativePromise.defer();
1688
- innerFlow.execute(function() {
1689
- return block.promise;
1690
- }, 'block inner flow');
1698
+ var block = defer();
1699
+ innerFlow.execute(function() {
1700
+ return block.promise;
1701
+ }, 'block inner flow');
1691
1702
 
1692
- outerFlow.execute(function() {
1693
- block.resolve();
1694
- return innerFlow.execute(function() {
1695
- promise.rejected(new StubError);
1696
- }, 'trigger unhandled rejection error');
1697
- }, 'run test');
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
- return NativePromise.all([
1700
- waitForIdle(innerFlow),
1701
- waitForAbort(outerFlow).then(assertIsStubError)
1702
- ]);
1703
- });
1710
+ return NativePromise.all([
1711
+ waitForIdle(innerFlow),
1712
+ waitForAbort(outerFlow).then(assertIsStubError)
1713
+ ]);
1714
+ });
1704
1715
 
1705
- it('testFailsIfErrbackThrows', function() {
1706
- promise.rejected('').then(null, throwStubError);
1707
- return waitForAbort().then(assertIsStubError);
1708
- });
1716
+ it('testFailsIfErrbackThrows', function() {
1717
+ promise.rejected('').then(null, throwStubError);
1718
+ return waitForAbort().then(assertIsStubError);
1719
+ });
1709
1720
 
1710
- it('testFailsIfCallbackReturnsRejectedPromise', function() {
1711
- promise.fulfilled().then(function() {
1712
- return promise.rejected(new StubError);
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
- it('testAbortsFrameIfTaskFails', function() {
1718
- promise.fulfilled().then(function() {
1719
- promise.controlFlow().execute(throwStubError);
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
- it('testAbortsFramePromisedChainedFromTaskIsNotHandled', function() {
1725
- promise.fulfilled().then(function() {
1726
- promise.controlFlow().execute(function() {}).
1727
- then(throwStubError);
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
- it('testTrapsChainedUnhandledRejectionsWithinAFrame', function() {
1733
- var pair = callbackPair(null, assertIsStubError);
1734
- promise.fulfilled().then(function() {
1735
- promise.controlFlow().execute(function() {}).
1736
- then(throwStubError);
1737
- }).then(pair.callback, pair.errback);
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
- return waitForIdle().then(pair.assertErrback);
1740
- });
1750
+ return waitForIdle().then(pair.assertErrback);
1751
+ });
1741
1752
 
1742
- it('testCancelsRemainingTasksIfFrameThrowsDuringScheduling', function() {
1743
- var task1, task2;
1744
- var pair = callbackPair(null, assertIsStubError);
1745
- var flow = promise.controlFlow();
1746
- flow.execute(function() {
1747
- task1 = flow.execute(function() {});
1748
- task2 = flow.execute(function() {});
1749
- throw new StubError;
1750
- }).then(pair.callback, pair.errback);
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
- it('testCancelsRemainingTasksInFrameIfATaskFails', function() {
1771
- var task;
1772
- var pair = callbackPair(null, assertIsStubError);
1773
- var flow = promise.controlFlow();
1774
- flow.execute(function() {
1775
- flow.execute(throwStubError);
1776
- task = flow.execute(function() {});
1777
- }).then(pair.callback, pair.errback);
1778
-
1779
- return waitForIdle().then(pair.assertErrback).then(function() {
1780
- assert.ok(!task.isPending());
1781
- pair = callbackPair();
1782
- task.then(pair.callback, pair.errback);
1783
- }).then(function() {
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
- it('testDoesNotModifyRejectionErrorIfPromiseNotInsideAFlow', function() {
1789
- var error = Error('original message');
1790
- var originalStack = error.stack;
1791
- var originalStr = error.toString();
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
- var pair = callbackPair(null, function(e) {
1794
- assert.equal(error, e);
1795
- assert.equal('original message', e.message);
1796
- assert.equal(originalStack, e.stack);
1797
- assert.equal(originalStr, e.toString());
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
- promise.rejected(error).then(pair.callback, pair.errback);
1801
- return waitForIdle().then(pair.assertErrback);
1802
- });
1796
+ it('testDoesNotModifyRejectionErrorIfPromiseNotInsideAFlow', function() {
1797
+ var error = Error('original message');
1798
+ var originalStack = error.stack;
1799
+ var originalStr = error.toString();
1803
1800
 
1804
- /** See https://github.com/SeleniumHQ/selenium/issues/444 */
1805
- it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_1', function() {
1806
- var messages = [];
1807
- flow.execute(function() {
1808
- return promise.fulfilled(['a', 'b', 'c', 'd']);
1809
- }, 'start').then(function(steps) {
1810
- steps.forEach(function(step) {
1811
- promise.fulfilled(step)
1812
- .then(function() {
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
- /** See https://github.com/SeleniumHQ/selenium/issues/444 */
1827
- it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_2', function() {
1828
- var messages = [];
1829
- flow.execute(function() {
1830
- return promise.fulfilled(['a', 'b', 'c', 'd']);
1831
- }, 'start').then(function(steps) {
1832
- steps.forEach(function(step) {
1833
- promise.fulfilled(step)
1834
- .then(function() {
1835
- messages.push(step + '.1');
1836
- }).then(function() {
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
- return waitForIdle().then(function() {
1844
- assert.deepEqual(
1845
- ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'],
1846
- messages);
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
- /** See https://github.com/SeleniumHQ/selenium/issues/444 */
1851
- it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_3', function() {
1852
- var messages = [];
1853
- flow.execute(function() {
1854
- return promise.fulfilled(['a', 'b', 'c', 'd']);
1855
- }, 'start').then(function(steps) {
1856
- steps.forEach(function(step) {
1857
- promise.fulfilled(step)
1858
- .then(function(){})
1859
- .then(function() {
1860
- messages.push(step + '.1');
1861
- return flow.execute(function() {}, step + '.1');
1862
- }).then(function() {
1863
- flow.execute(function() {}, step + '.2').then(function(text) {
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
- return waitForIdle().then(function() {
1870
- assert.deepEqual(
1871
- ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'],
1872
- messages);
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
- /** See https://github.com/SeleniumHQ/selenium/issues/363 */
1877
- it('testTasksScheduledInASeparateTurnOfTheEventLoopGetASeparateTaskQueue_2', function() {
1878
- scheduleAction('a', () => promise.delayed(10));
1879
- schedule('b');
1880
- setTimeout(() => schedule('c'), 0);
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
- return waitForIdle().then(function() {
1883
- assertFlowHistory('a', 'c', 'b');
1890
+ return waitForIdle().then(function() {
1891
+ assertFlowHistory('a', 'c', 'b');
1892
+ });
1884
1893
  });
1885
- });
1886
1894
 
1887
- /** See https://github.com/SeleniumHQ/selenium/issues/363 */
1888
- it('testTasksScheduledInASeparateTurnOfTheEventLoopGetASeparateTaskQueue_2', function() {
1889
- scheduleAction('a', () => promise.delayed(10));
1890
- schedule('b');
1891
- schedule('c');
1892
- setTimeout(function() {
1893
- schedule('d');
1894
- scheduleAction('e', () => promise.delayed(10));
1895
- schedule('f');
1896
- }, 0);
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
- /** See https://github.com/SeleniumHQ/selenium/issues/363 */
1904
- it('testCanSynchronizeTasksFromAdjacentTaskQueues', function() {
1905
- var task1 = scheduleAction('a', () => promise.delayed(10));
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
- describe('testCancellingAScheduledTask', function() {
1918
- it('1', function() {
1919
- var called = false;
1920
- var task1 = scheduleAction('a', () => called = true);
1921
- task1.cancel('no soup for you');
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
- assert.ok(!called);
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
- it('2', function() {
1934
- schedule('a');
1935
- var called = false;
1936
- var task2 = scheduleAction('b', () => called = true);
1937
- schedule('c');
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
- task2.cancel('no soup for you');
1940
-
1941
- return waitForIdle().then(function() {
1942
- assert.ok(!called);
1943
- assertFlowHistory('a', 'c');
1944
- return task2.catch(function(e) {
1945
- assert.ok(e instanceof promise.CancellationError);
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
- it('3', function() {
1952
- var called = false;
1953
- var task = scheduleAction('a', () => called = true);
1954
- task.cancel(new StubError);
1941
+ it('2', function() {
1942
+ schedule('a');
1943
+ var called = false;
1944
+ var task2 = scheduleAction('b', () => called = true);
1945
+ schedule('c');
1955
1946
 
1956
- return waitForIdle().then(function() {
1957
- assert.ok(!called);
1958
- assertFlowHistory();
1959
- return task.catch(function(e) {
1960
- assert.ok(e instanceof promise.CancellationError);
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
- it('4', function() {
1966
- var seen = [];
1967
- var task = scheduleAction('a', () => seen.push(1))
1968
- .then(() => seen.push(2))
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
- return waitForIdle().then(function() {
1975
- assert.deepEqual([], seen);
1976
- assertFlowHistory();
1977
- return task.catch(function(e) {
1978
- assert.ok(e instanceof promise.CancellationError);
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
- it('fromWithinAnExecutingTask', function() {
1984
- var called = false;
1985
- var task;
1986
- scheduleAction('a', function() {
1987
- task.cancel('no soup for you');
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
- return waitForIdle().then(function() {
1993
- assert.ok(!called);
1994
- assertFlowHistory('a', 'c');
1995
- return task.catch(function(e) {
1996
- assert.ok(e instanceof promise.CancellationError);
1997
- assert.equal('no soup for you', e.message);
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
- it('testCancellingAPendingTask', function() {
2004
- var order = [];
2005
- var unresolved = promise.defer();
2011
+ it('testCancellingAPendingTask', function() {
2012
+ var order = [];
2013
+ var unresolved = promise.defer();
2006
2014
 
2007
- var innerTask;
2008
- var outerTask = scheduleAction('a', function() {
2009
- order.push(1);
2015
+ var innerTask;
2016
+ var outerTask = scheduleAction('a', function() {
2017
+ order.push(1);
2010
2018
 
2011
- // Schedule a task that will never finish.
2012
- innerTask = scheduleAction('a.1', function() {
2013
- return unresolved.promise;
2014
- });
2019
+ // Schedule a task that will never finish.
2020
+ innerTask = scheduleAction('a.1', function() {
2021
+ return unresolved.promise;
2022
+ });
2015
2023
 
2016
- // Since the outerTask is cancelled below, innerTask should be cancelled
2017
- // with a DiscardedTaskError, which means its callbacks are silently
2018
- // dropped - so this should never execute.
2019
- innerTask.catch(function(e) {
2020
- order.push(2);
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
- outerTask.catch(function(e) {
2026
- order.push(3);
2027
- assert.ok(e instanceof promise.CancellationError);
2028
- assert.equal('no soup for you', e.message);
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
- unresolved.promise.catch(function(e) {
2032
- order.push(4);
2033
- assert.ok(e instanceof promise.CancellationError);
2034
- });
2039
+ unresolved.promise.catch(function(e) {
2040
+ order.push(4);
2041
+ assert.ok(e instanceof promise.CancellationError);
2042
+ });
2035
2043
 
2036
- return timeout(10).then(function() {
2037
- assert.deepEqual([1], order);
2038
- assert.ok(unresolved.promise.isPending());
2044
+ return timeout(10).then(function() {
2045
+ assert.deepEqual([1], order);
2039
2046
 
2040
- outerTask.cancel('no soup for you');
2041
- return waitForIdle();
2042
- }).then(function() {
2043
- assertFlowHistory('a', 'a.1', 'b');
2044
- assert.deepEqual([1, 3, 4], order);
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
- it('testCancellingAPendingPromiseCallback', function() {
2049
- var called = false;
2055
+ it('testCancellingAPendingPromiseCallback', function() {
2056
+ var called = false;
2050
2057
 
2051
- var root = promise.fulfilled();
2052
- root.then(function() {
2053
- cb2.cancel('no soup for you');
2054
- });
2058
+ var root = promise.fulfilled();
2059
+ root.then(function() {
2060
+ cb2.cancel('no soup for you');
2061
+ });
2055
2062
 
2056
- var cb2 = root.then(fail, fail); // These callbacks should never be called.
2057
- cb2.then(fail, function(e) {
2058
- called = true;
2059
- assert.ok(e instanceof promise.CancellationError);
2060
- assert.equal('no soup for you', e.message);
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
- return waitForIdle().then(function() {
2064
- assert.ok(called);
2070
+ return waitForIdle().then(function() {
2071
+ assert.ok(called);
2072
+ });
2065
2073
  });
2066
- });
2067
2074
 
2068
- describe('testResetFlow', function() {
2069
- it('1', function() {
2070
- var called = 0;
2071
- var task = flow.execute(() => called++);
2072
- task.finally(() => called++);
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
- return new Promise(function(fulfill) {
2075
- flow.once('reset', fulfill);
2076
- flow.reset();
2081
+ return new Promise(function(fulfill) {
2082
+ flow.once('reset', fulfill);
2083
+ flow.reset();
2077
2084
 
2078
- }).then(function() {
2079
- assert.equal(0, called);
2080
- assert.ok(!task.isPending());
2081
- return task;
2085
+ }).then(function() {
2086
+ assert.equal(0, called);
2087
+ return task;
2082
2088
 
2083
- }).then(fail, function(e) {
2084
- assert.ok(e instanceof promise.CancellationError);
2085
- assert.equal('ControlFlow was reset', e.message);
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
- it('2', function() {
2090
- var called = 0;
2091
- var task1 = flow.execute(() => called++);
2092
- task1.finally(() => called++);
2095
+ it('2', function() {
2096
+ var called = 0;
2097
+ var task1 = flow.execute(() => called++);
2098
+ task1.finally(() => called++);
2093
2099
 
2094
- var task2 = flow.execute(() => called++);
2095
- task2.finally(() => called++);
2100
+ var task2 = flow.execute(() => called++);
2101
+ task2.finally(() => called++);
2096
2102
 
2097
- var task3 = flow.execute(() => called++);
2098
- task3.finally(() => called++);
2103
+ var task3 = flow.execute(() => called++);
2104
+ task3.finally(() => called++);
2099
2105
 
2100
- return new Promise(function(fulfill) {
2101
- flow.once('reset', fulfill);
2102
- flow.reset();
2106
+ return new Promise(function(fulfill) {
2107
+ flow.once('reset', fulfill);
2108
+ flow.reset();
2103
2109
 
2104
- }).then(function() {
2105
- assert.equal(0, called);
2106
- assert.ok(!task1.isPending());
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
- describe('testPromiseFulfilledInsideTask', function() {
2114
- it('1', function() {
2115
- var order = [];
2116
+ describe('testPromiseFulfilledInsideTask', function() {
2117
+ it('1', function() {
2118
+ var order = [];
2116
2119
 
2117
- flow.execute(function() {
2118
- var d = promise.defer();
2120
+ flow.execute(function() {
2121
+ var d = promise.defer();
2119
2122
 
2120
- d.promise.then(() => order.push('a'));
2121
- d.promise.then(() => order.push('b'));
2122
- d.promise.then(() => order.push('c'));
2123
- d.fulfill();
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
- flow.execute(() => order.push('d'));
2128
+ flow.execute(() => order.push('d'));
2126
2129
 
2127
- }).then(() => order.push('fin'));
2130
+ }).then(() => order.push('fin'));
2128
2131
 
2129
- return waitForIdle().then(function() {
2130
- assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
2132
+ return waitForIdle().then(function() {
2133
+ assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
2134
+ });
2131
2135
  });
2132
- });
2133
2136
 
2134
- it('2', function() {
2135
- var order = [];
2137
+ it('2', function() {
2138
+ var order = [];
2136
2139
 
2137
- flow.execute(function() {
2138
- flow.execute(() => order.push('a'));
2139
- flow.execute(() => order.push('b'));
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(() => order.push('e'));
2164
+ flow.execute(function() {
2165
+ flow.execute(() => order.push('a'));
2166
+ flow.execute(() => order.push('b'));
2147
2167
 
2148
- }).then(() => order.push('fin'));
2168
+ d.promise.then(() => order.push('e'));
2169
+ d.fulfill();
2149
2170
 
2150
- return waitForIdle().then(function() {
2151
- assert.deepEqual(['a', 'b', 'c', 'd', 'e', 'fin'], order);
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
- it('3', function() {
2156
- var order = [];
2157
- var d = promise.defer();
2158
- d.promise.then(() => order.push('c'));
2159
- d.promise.then(() => order.push('d'));
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
- flow.execute(function() {
2162
- flow.execute(() => order.push('a'));
2163
- flow.execute(() => order.push('b'));
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
- d.promise.then(() => order.push('e'));
2166
- d.fulfill();
2194
+ d.promise.then(() => order.push('g'));
2195
+ d.fulfill();
2167
2196
 
2168
- flow.execute(() => order.push('f'));
2197
+ flow.execute(() => order.push('h'));
2169
2198
 
2170
- }).then(() => order.push('fin'));
2199
+ }).then(() => order.push('fin'));
2171
2200
 
2172
- return waitForIdle().then(function() {
2173
- assert.deepEqual(['c', 'd', 'a', 'b', 'e', 'f', 'fin'], order);
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
- it('4', function() {
2178
- var order = [];
2179
- var d = promise.defer();
2180
- d.promise.then(() => order.push('a'));
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('c');
2186
- flow.execute(() => order.push('d'));
2187
- d.promise.then(() => order.push('e'));
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
- flow.execute(() => order.push('f'));
2190
-
2191
- d.promise.then(() => order.push('g'));
2192
- d.fulfill();
2222
+ });
2193
2223
 
2194
- flow.execute(() => order.push('h'));
2224
+ it('2', function() {
2225
+ var order = [];
2195
2226
 
2196
- }).then(() => order.push('fin'));
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
- return waitForIdle().then(function() {
2199
- assert.deepEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'fin'], order);
2233
+ return waitForIdle().then(function() {
2234
+ assert.deepEqual(['a', 'c', 'b', 'fin'], order);
2235
+ });
2200
2236
  });
2201
2237
  });
2202
- });
2203
2238
 
2204
- describe('testSettledPromiseCallbacksInsideATask', function() {
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
- flow.execute(() => order.push('a'));
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
- it('2', function() {
2222
- var order = [];
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', 'b', 'fin'], order);
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
- flow.execute(function() {
2240
- var d = promise.defer();
2241
-
2242
- // This is a normal promise, not a task, so the task for this callback is
2243
- // considered volatile. Volatile tasks should be skipped when they reach
2244
- // the front of the task queue.
2245
- d.promise.then(() => order.push('a'));
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
- flow.execute(() => order.push('e'));
2254
-
2255
- }).then(() => order.push('fin'));
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
- return waitForIdle().then(function() {
2258
- assert.deepEqual(['b', 'a', 'c', 'd', 'e', 'fin'], order);
2259
- });
2260
- });
2281
+ setTimeout(() => root.fulfill(), 20);
2261
2282
 
2262
- it('testCallbackDependenciesDoNotDeadlock', function() {
2263
- var order = [];
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
  });