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
@@ -21,6 +21,7 @@ const assert = require('assert');
21
21
 
22
22
  const testutil = require('./testutil');
23
23
  const promise = require('../../lib/promise');
24
+ const {enablePromiseManager, promiseManagerSuite} = require('../../lib/test/promise');
24
25
 
25
26
  // Aliases for readability.
26
27
  const NativePromise = Promise;
@@ -36,1026 +37,1054 @@ describe('promise', function() {
36
37
  var app, uncaughtExceptions;
37
38
 
38
39
  beforeEach(function setUp() {
39
- promise.LONG_STACK_TRACES = false;
40
- uncaughtExceptions = [];
40
+ if (promise.USE_PROMISE_MANAGER) {
41
+ promise.LONG_STACK_TRACES = false;
42
+ uncaughtExceptions = [];
41
43
 
42
- app = promise.controlFlow();
43
- app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
44
- (e) => uncaughtExceptions.push(e));
44
+ app = promise.controlFlow();
45
+ app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
46
+ (e) => uncaughtExceptions.push(e));
47
+ }
45
48
  });
46
49
 
47
50
  afterEach(function tearDown() {
48
- app.reset();
49
- promise.setDefaultFlow(new promise.ControlFlow);
50
- assert.deepEqual([], uncaughtExceptions,
51
- 'Did not expect any uncaught exceptions');
52
- promise.LONG_STACK_TRACES = false;
51
+ if (promise.USE_PROMISE_MANAGER) {
52
+ app.reset();
53
+ promise.setDefaultFlow(new promise.ControlFlow);
54
+ assert.deepEqual([], uncaughtExceptions,
55
+ 'Did not expect any uncaught exceptions');
56
+ promise.LONG_STACK_TRACES = false;
57
+ }
53
58
  });
54
59
 
55
60
  const assertIsPromise = (p) => assert.ok(promise.isPromise(p));
56
61
  const assertNotPromise = (v) => assert.ok(!promise.isPromise(v));
57
62
 
63
+ function defer() {
64
+ let d = {};
65
+ let promise = new Promise((resolve, reject) => {
66
+ Object.assign(d, {resolve, reject});
67
+ });
68
+ d.promise = promise;
69
+ return d;
70
+ }
71
+
58
72
  function createRejectedPromise(reason) {
59
- var p = promise.rejected(reason);
60
- p.catch(function() {});
73
+ var p = Promise.reject(reason);
74
+ p.catch(function() {}); // Silence unhandled rejection handlers.
61
75
  return p;
62
76
  }
63
77
 
64
- it('testCanDetectPromiseLikeObjects', function() {
65
- assertIsPromise(new promise.Promise(function(fulfill) {
66
- fulfill();
67
- }));
68
- assertIsPromise(new promise.Deferred().promise);
69
- assertIsPromise({then:function() {}});
70
-
71
- assertNotPromise(new promise.Deferred());
72
- assertNotPromise(undefined);
73
- assertNotPromise(null);
74
- assertNotPromise('');
75
- assertNotPromise(true);
76
- assertNotPromise(false);
77
- assertNotPromise(1);
78
- assertNotPromise({});
79
- assertNotPromise({then:1});
80
- assertNotPromise({then:true});
81
- assertNotPromise({then:''});
82
- });
83
-
84
- describe('then', function() {
85
- it('returnsOwnPromiseIfNoCallbacksWereGiven', function() {
86
- var deferred = new promise.Deferred();
87
- assert.equal(deferred.promise, deferred.promise.then());
88
- assert.equal(deferred.promise, deferred.promise.catch());
89
- assert.equal(deferred.promise, promise.when(deferred.promise));
90
- });
91
-
92
- it('stillConsideredUnHandledIfNoCallbacksWereGivenOnCallsToThen', function() {
93
- promise.rejected(new StubError).then();
94
- var handler = callbackHelper(assertIsStubError);
95
-
96
- // so tearDown() doesn't throw
97
- app.removeAllListeners();
98
- app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, handler);
99
- return NativePromise.resolve().then(() => handler.assertCalled());
100
- });
101
- });
78
+ enablePromiseManager(() => {
79
+ it('testCanDetectPromiseLikeObjects', function() {
80
+ assertIsPromise(new promise.Promise(function(fulfill) {
81
+ fulfill();
82
+ }));
83
+ assertIsPromise(new promise.Deferred().promise);
84
+ assertIsPromise(Promise.resolve(123));
85
+ assertIsPromise({then:function() {}});
86
+
87
+ assertNotPromise(new promise.Deferred());
88
+ assertNotPromise(undefined);
89
+ assertNotPromise(null);
90
+ assertNotPromise('');
91
+ assertNotPromise(true);
92
+ assertNotPromise(false);
93
+ assertNotPromise(1);
94
+ assertNotPromise({});
95
+ assertNotPromise({then:1});
96
+ assertNotPromise({then:true});
97
+ assertNotPromise({then:''});
98
+ });
99
+
100
+ describe('then', function() {
101
+ it('returnsOwnPromiseIfNoCallbacksWereGiven', function() {
102
+ var deferred = new promise.Deferred();
103
+ assert.equal(deferred.promise, deferred.promise.then());
104
+ assert.equal(deferred.promise, deferred.promise.catch());
105
+ assert.equal(deferred.promise, promise.when(deferred.promise));
106
+ });
102
107
 
103
- describe('finally', function() {
104
- it('nonFailingCallbackDoesNotSuppressOriginalError', function() {
105
- var done = callbackHelper(assertIsStubError);
106
- return promise.rejected(new StubError).
107
- finally(function() {}).
108
- catch(done).
109
- finally(done.assertCalled);
108
+ it('stillConsideredUnHandledIfNoCallbacksWereGivenOnCallsToThen', function() {
109
+ promise.rejected(new StubError).then();
110
+ var handler = callbackHelper(assertIsStubError);
111
+
112
+ // so tearDown() doesn't throw
113
+ app.removeAllListeners();
114
+ app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, handler);
115
+ return NativePromise.resolve()
116
+ // Macro yield so the uncaught exception has a chance to trigger.
117
+ .then(() => new NativePromise(resolve => setTimeout(resolve, 0)))
118
+ .then(() => handler.assertCalled());
119
+ });
110
120
  });
111
121
 
112
- it('failingCallbackSuppressesOriginalError', function() {
113
- var done = callbackHelper(assertIsStubError);
114
- return promise.rejected(new Error('original')).
115
- finally(throwStubError).
116
- catch(done).
117
- finally(done.assertCalled);
118
- });
122
+ describe('finally', function() {
123
+ it('nonFailingCallbackDoesNotSuppressOriginalError', function() {
124
+ var done = callbackHelper(assertIsStubError);
125
+ return promise.rejected(new StubError).
126
+ finally(function() {}).
127
+ catch(done).
128
+ finally(done.assertCalled);
129
+ });
119
130
 
120
- it('callbackThrowsAfterFulfilledPromise', function() {
121
- var done = callbackHelper(assertIsStubError);
122
- return promise.fulfilled().
123
- finally(throwStubError).
124
- catch(done).
125
- finally(done.assertCalled);
126
- });
131
+ it('failingCallbackSuppressesOriginalError', function() {
132
+ var done = callbackHelper(assertIsStubError);
133
+ return promise.rejected(new Error('original')).
134
+ finally(throwStubError).
135
+ catch(done).
136
+ finally(done.assertCalled);
137
+ });
127
138
 
128
- it('callbackReturnsRejectedPromise', function() {
129
- var done = callbackHelper(assertIsStubError);
130
- return promise.fulfilled().
131
- finally(function() {
132
- return promise.rejected(new StubError);
133
- }).
134
- catch(done).
135
- finally(done.assertCalled);
136
- });
137
- });
139
+ it('callbackThrowsAfterFulfilledPromise', function() {
140
+ var done = callbackHelper(assertIsStubError);
141
+ return promise.fulfilled().
142
+ finally(throwStubError).
143
+ catch(done).
144
+ finally(done.assertCalled);
145
+ });
138
146
 
139
- describe('cancel', function() {
140
- it('passesTheCancellationReasonToReject', function() {
141
- var d = new promise.Deferred();
142
- var res = d.promise.then(assert.fail, function(e) {
143
- assert.ok(e instanceof promise.CancellationError);
144
- assert.equal('because i said so', e.message);
147
+ it('callbackReturnsRejectedPromise', function() {
148
+ var done = callbackHelper(assertIsStubError);
149
+ return promise.fulfilled().
150
+ finally(function() {
151
+ return promise.rejected(new StubError);
152
+ }).
153
+ catch(done).
154
+ finally(done.assertCalled);
145
155
  });
146
- d.promise.cancel('because i said so');
147
- return res;
148
156
  });
149
157
 
150
- describe('can cancel original promise from its child;', function() {
151
- it('child created by then()', function() {
158
+ describe('cancel', function() {
159
+ it('passesTheCancellationReasonToReject', function() {
152
160
  var d = new promise.Deferred();
153
- var p = d.promise.then(assert.fail, function(e) {
161
+ var res = d.promise.then(assert.fail, function(e) {
154
162
  assert.ok(e instanceof promise.CancellationError);
155
163
  assert.equal('because i said so', e.message);
156
- return 123;
157
164
  });
158
-
159
- p.cancel('because i said so');
160
- return p.then(v => assert.equal(123, v));
161
- });
162
-
163
- it('child linked by resolving with parent', function() {
164
- let parent = promise.defer();
165
- let child = new promise.Promise(resolve => resolve(parent.promise));
166
- child.cancel('all done');
167
-
168
- return parent.promise.then(
169
- () => assert.fail('expected a cancellation'),
170
- e => {
171
- assert.ok(e instanceof promise.CancellationError);
172
- assert.equal('all done', e.message);
173
- });
174
- });
175
-
176
- it('grand child through thenable chain', function() {
177
- let p = new promise.Promise(function() {/* never resolve*/});
178
-
179
- let noop = function() {};
180
- let gc = p.then(noop).then(noop).then(noop);
181
- gc.cancel('stop!');
182
-
183
- return p.then(
184
- () => assert.fail('expected to be cancelled'),
185
- (e) => {
186
- assert.ok(e instanceof promise.CancellationError);
187
- assert.equal('stop!', e.message);
188
- });
165
+ d.promise.cancel('because i said so');
166
+ return res;
189
167
  });
190
168
 
191
- it('grand child through thenable chain started at resolve', function() {
192
- function noop() {}
193
-
194
- let parent = promise.defer();
195
- let child = new promise.Promise(resolve => resolve(parent.promise));
196
- let grandChild = child.then(noop).then(noop).then(noop);
197
- grandChild.cancel('all done');
198
-
199
- return parent.promise.then(
200
- () => assert.fail('expected a cancellation'),
201
- e => {
202
- assert.ok(e instanceof promise.CancellationError);
203
- assert.equal('all done', e.message);
204
- });
205
- });
169
+ describe('can cancel original promise from its child;', function() {
170
+ it('child created by then()', function() {
171
+ var d = new promise.Deferred();
172
+ var p = d.promise.then(assert.fail, function(e) {
173
+ assert.ok(e instanceof promise.CancellationError);
174
+ assert.equal('because i said so', e.message);
175
+ return 123;
176
+ });
206
177
 
207
- it('"parent" is a Thenable', function() {
208
- function noop() {}
178
+ p.cancel('because i said so');
179
+ return p.then(v => assert.equal(123, v));
180
+ });
209
181
 
210
- class FakeThenable {
211
- constructor(p) {
212
- this.promise = p;
213
- }
182
+ it('child linked by resolving with parent', function() {
183
+ let parent = promise.defer();
184
+ let child = new promise.Promise(resolve => resolve(parent.promise));
185
+ child.cancel('all done');
214
186
 
215
- cancel(reason) {
216
- this.promise.cancel(reason);
217
- }
218
-
219
- then(cb, eb) {
220
- let result = this.promise.then(cb, eb);
221
- return new FakeThenable(result);
222
- }
223
- }
224
- promise.Thenable.addImplementation(FakeThenable);
187
+ return parent.promise.then(
188
+ () => assert.fail('expected a cancellation'),
189
+ e => {
190
+ assert.ok(e instanceof promise.CancellationError);
191
+ assert.equal('all done', e.message);
192
+ });
193
+ });
225
194
 
226
- let root = new promise.Promise(noop);
227
- let thenable = new FakeThenable(root);
228
- assert.ok(promise.Thenable.isImplementation(thenable));
195
+ it('grand child through thenable chain', function() {
196
+ let p = new promise.Promise(function() {/* never resolve*/});
229
197
 
230
- let child = new promise.Promise(resolve => resolve(thenable));
231
- assert.ok(child instanceof promise.Promise);
232
- child.cancel('stop!');
198
+ let noop = function() {};
199
+ let gc = p.then(noop).then(noop).then(noop);
200
+ gc.cancel('stop!');
233
201
 
234
- function assertStopped(p) {
235
202
  return p.then(
236
- () => assert.fail('not stopped!'),
203
+ () => assert.fail('expected to be cancelled'),
237
204
  (e) => {
238
205
  assert.ok(e instanceof promise.CancellationError);
239
206
  assert.equal('stop!', e.message);
240
207
  });
241
- }
242
-
243
- return assertStopped(child).then(() => assertStopped(root));
244
- });
245
- });
208
+ });
246
209
 
247
- it('canCancelATimeout', function() {
248
- var p = promise.delayed(25)
249
- .then(assert.fail, (e) => e instanceof promise.CancellationError);
250
- setTimeout(() => p.cancel(), 20);
251
- p.cancel();
252
- return p;
253
- });
210
+ it('grand child through thenable chain started at resolve', function() {
211
+ function noop() {}
254
212
 
255
- it('can cancel timeout from grandchild', function() {
256
- });
213
+ let parent = promise.defer();
214
+ let child = new promise.Promise(resolve => resolve(parent.promise));
215
+ let grandChild = child.then(noop).then(noop).then(noop);
216
+ grandChild.cancel('all done');
257
217
 
258
- it('cancelIsANoopOnceAPromiseHasBeenFulfilled', function() {
259
- var p = promise.fulfilled(123);
260
- p.cancel();
261
- return p.then((v) => assert.equal(123, v));
262
- });
218
+ return parent.promise.then(
219
+ () => assert.fail('expected a cancellation'),
220
+ e => {
221
+ assert.ok(e instanceof promise.CancellationError);
222
+ assert.equal('all done', e.message);
223
+ });
224
+ });
263
225
 
264
- it('cancelIsANoopOnceAPromiseHasBeenRejected', function() {
265
- var p = promise.rejected(new StubError);
266
- p.cancel();
226
+ it('"parent" is a CancellableThenable', function() {
227
+ function noop() {}
267
228
 
268
- var pair = callbackPair(null, assertIsStubError);
269
- return p.then(assert.fail, assertIsStubError);
270
- });
229
+ class FakeThenable {
230
+ constructor(p) {
231
+ this.promise = p;
232
+ }
271
233
 
272
- it('noopCancelTriggeredOnCallbackOfResolvedPromise', function() {
273
- var d = promise.defer();
274
- var p = d.promise.then();
234
+ cancel(reason) {
235
+ this.promise.cancel(reason);
236
+ }
275
237
 
276
- d.fulfill();
277
- p.cancel(); // This should not throw.
278
- return p; // This should not trigger a failure.
279
- });
280
- });
238
+ then(cb, eb) {
239
+ let result = this.promise.then(cb, eb);
240
+ return new FakeThenable(result);
241
+ }
242
+ }
243
+ promise.CancellableThenable.addImplementation(FakeThenable);
244
+
245
+ let root = new promise.Promise(noop);
246
+ let thenable = new FakeThenable(root);
247
+ assert.ok(promise.Thenable.isImplementation(thenable));
248
+ assert.ok(promise.CancellableThenable.isImplementation(thenable));
249
+
250
+ let child = new promise.Promise(resolve => resolve(thenable));
251
+ assert.ok(child instanceof promise.Promise);
252
+ child.cancel('stop!');
253
+
254
+ function assertStopped(p) {
255
+ return p.then(
256
+ () => assert.fail('not stopped!'),
257
+ (e) => {
258
+ assert.ok(e instanceof promise.CancellationError);
259
+ assert.equal('stop!', e.message);
260
+ });
261
+ }
281
262
 
282
- describe('when', function() {
283
- it('ReturnsAResolvedPromiseIfGivenANonPromiseValue', function() {
284
- var ret = promise.when('abc');
285
- assertIsPromise(ret);
286
- return ret.then((value) => assert.equal('abc', value));
287
- });
263
+ return assertStopped(child).then(() => assertStopped(root));
264
+ });
265
+ });
288
266
 
289
- it('PassesRawErrorsToCallbacks', function() {
290
- var error = new Error('boo!');
291
- return promise.when(error, function(value) {
292
- assert.equal(error, value);
267
+ it('canCancelATimeout', function() {
268
+ var p = promise.delayed(25)
269
+ .then(assert.fail, (e) => e instanceof promise.CancellationError);
270
+ setTimeout(() => p.cancel(), 20);
271
+ p.cancel();
272
+ return p;
293
273
  });
294
- });
295
274
 
296
- it('WaitsForValueToBeResolvedBeforeInvokingCallback', function() {
297
- var d = new promise.Deferred(), callback;
298
- let result = promise.when(d.promise, callback = callbackHelper(function(value) {
299
- assert.equal('hi', value);
300
- }));
301
- callback.assertNotCalled();
302
- d.fulfill('hi');
303
- return result.then(callback.assertCalled);
304
- });
305
- });
275
+ it('can cancel timeout from grandchild', function() {
276
+ });
306
277
 
307
- it('firesUncaughtExceptionEventIfRejectionNeverHandled', function() {
308
- promise.rejected(new StubError);
309
- var handler = callbackHelper(assertIsStubError);
278
+ it('cancelIsANoopOnceAPromiseHasBeenFulfilled', function() {
279
+ var p = promise.fulfilled(123);
280
+ p.cancel();
281
+ return p.then((v) => assert.equal(123, v));
282
+ });
310
283
 
311
- // so tearDown() doesn't throw
312
- app.removeAllListeners();
313
- app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, handler);
284
+ it('cancelIsANoopOnceAPromiseHasBeenRejected', function() {
285
+ var p = promise.rejected(new StubError);
286
+ p.cancel();
314
287
 
315
- return NativePromise.resolve().then(handler.assertCalled);
316
- });
288
+ var pair = callbackPair(null, assertIsStubError);
289
+ return p.then(assert.fail, assertIsStubError);
290
+ });
317
291
 
318
- it('cannotResolveADeferredWithItself', function() {
319
- var deferred = new promise.Deferred();
320
- assert.throws(() => deferred.fulfill(deferred));
321
- assert.throws(() => deferred.reject(deferred));
322
- });
292
+ it('noopCancelTriggeredOnCallbackOfResolvedPromise', function() {
293
+ var d = promise.defer();
294
+ var p = d.promise.then();
323
295
 
324
- describe('fullyResolved', function() {
325
- it('primitives', function() {
326
- function runTest(value) {
327
- var callback, errback;
328
- return promise.fullyResolved(value)
329
- .then((resolved) => assert.equal(value, resolved));
330
- }
331
- return runTest(true)
332
- .then(() => runTest(function() {}))
333
- .then(() => runTest(null))
334
- .then(() => runTest(123))
335
- .then(() => runTest('foo bar'))
336
- .then(() => runTest(undefined));
296
+ d.fulfill();
297
+ p.cancel(); // This should not throw.
298
+ return p; // This should not trigger a failure.
299
+ });
337
300
  });
301
+ });
338
302
 
339
- it('arrayOfPrimitives', function() {
340
- var fn = function() {};
341
- var array = [true, fn, null, 123, '', undefined, 1];
342
- return promise.fullyResolved(array).then(function(resolved) {
343
- assert.equal(array, resolved);
344
- assert.deepEqual([true, fn, null, 123, '', undefined, 1],
345
- resolved);
303
+ promiseManagerSuite(() => {
304
+ describe('when', function() {
305
+ it('ReturnsAResolvedPromiseIfGivenANonPromiseValue', function() {
306
+ var ret = promise.when('abc');
307
+ assertIsPromise(ret);
308
+ return ret.then((value) => assert.equal('abc', value));
346
309
  });
347
- });
348
310
 
349
- it('nestedArrayOfPrimitives', function() {
350
- var fn = function() {};
351
- var array = [true, [fn, null, 123], '', undefined];
352
- return promise.fullyResolved(array)
353
- .then(function(resolved) {
354
- assert.equal(array, resolved);
355
- assert.deepEqual([true, [fn, null, 123], '', undefined], resolved);
356
- assert.deepEqual([fn, null, 123], resolved[1]);
357
- });
358
- });
311
+ it('PassesRawErrorsToCallbacks', function() {
312
+ var error = new Error('boo!');
313
+ return promise.when(error, function(value) {
314
+ assert.equal(error, value);
315
+ });
316
+ });
359
317
 
360
- it('arrayWithPromisedPrimitive', function() {
361
- return promise.fullyResolved([promise.fulfilled(123)])
362
- .then(function(resolved) {
363
- assert.deepEqual([123], resolved);
364
- });
318
+ it('WaitsForValueToBeResolvedBeforeInvokingCallback', function() {
319
+ let d = defer();
320
+ let callback;
321
+ let result = promise.when(d.promise, callback = callbackHelper(function(value) {
322
+ assert.equal('hi', value);
323
+ }));
324
+ callback.assertNotCalled();
325
+ d.resolve('hi');
326
+ return result.then(callback.assertCalled);
327
+ });
365
328
  });
366
329
 
367
- it('promiseResolvesToPrimitive', function() {
368
- return promise.fullyResolved(promise.fulfilled(123))
369
- .then((resolved) => assert.equal(123, resolved));
370
- });
330
+ describe('fullyResolved', function() {
331
+ it('primitives', function() {
332
+ function runTest(value) {
333
+ var callback, errback;
334
+ return promise.fullyResolved(value)
335
+ .then((resolved) => assert.equal(value, resolved));
336
+ }
337
+ return runTest(true)
338
+ .then(() => runTest(function() {}))
339
+ .then(() => runTest(null))
340
+ .then(() => runTest(123))
341
+ .then(() => runTest('foo bar'))
342
+ .then(() => runTest(undefined));
343
+ });
371
344
 
372
- it('promiseResolvesToArray', function() {
373
- var fn = function() {};
374
- var array = [true, [fn, null, 123], '', undefined];
375
- var aPromise = promise.fulfilled(array);
345
+ it('arrayOfPrimitives', function() {
346
+ var fn = function() {};
347
+ var array = [true, fn, null, 123, '', undefined, 1];
348
+ return promise.fullyResolved(array).then(function(resolved) {
349
+ assert.equal(array, resolved);
350
+ assert.deepEqual([true, fn, null, 123, '', undefined, 1],
351
+ resolved);
352
+ });
353
+ });
376
354
 
377
- var result = promise.fullyResolved(aPromise);
378
- return result.then(function(resolved) {
379
- assert.equal(array, resolved);
380
- assert.deepEqual([true, [fn, null, 123], '', undefined],
381
- resolved);
382
- assert.deepEqual([fn, null, 123], resolved[1]);
355
+ it('nestedArrayOfPrimitives', function() {
356
+ var fn = function() {};
357
+ var array = [true, [fn, null, 123], '', undefined];
358
+ return promise.fullyResolved(array)
359
+ .then(function(resolved) {
360
+ assert.equal(array, resolved);
361
+ assert.deepEqual([true, [fn, null, 123], '', undefined], resolved);
362
+ assert.deepEqual([fn, null, 123], resolved[1]);
363
+ });
383
364
  });
384
- });
385
365
 
386
- it('promiseResolvesToArrayWithPromises', function() {
387
- var nestedPromise = promise.fulfilled(123);
388
- var aPromise = promise.fulfilled([true, nestedPromise]);
389
- return promise.fullyResolved(aPromise)
390
- .then(function(resolved) {
391
- assert.deepEqual([true, 123], resolved);
392
- });
393
- });
366
+ it('arrayWithPromisedPrimitive', function() {
367
+ return promise.fullyResolved([Promise.resolve(123)])
368
+ .then(function(resolved) {
369
+ assert.deepEqual([123], resolved);
370
+ });
371
+ });
394
372
 
395
- it('rejectsIfArrayPromiseRejects', function() {
396
- var nestedPromise = createRejectedPromise(new StubError);
397
- var aPromise = promise.fulfilled([true, nestedPromise]);
373
+ it('promiseResolvesToPrimitive', function() {
374
+ return promise.fullyResolved(Promise.resolve(123))
375
+ .then((resolved) => assert.equal(123, resolved));
376
+ });
398
377
 
399
- var pair = callbackPair(null, assertIsStubError);
400
- return promise.fullyResolved(aPromise)
401
- .then(assert.fail, assertIsStubError);
402
- });
378
+ it('promiseResolvesToArray', function() {
379
+ var fn = function() {};
380
+ var array = [true, [fn, null, 123], '', undefined];
381
+ var aPromise = Promise.resolve(array);
382
+
383
+ var result = promise.fullyResolved(aPromise);
384
+ return result.then(function(resolved) {
385
+ assert.equal(array, resolved);
386
+ assert.deepEqual([true, [fn, null, 123], '', undefined],
387
+ resolved);
388
+ assert.deepEqual([fn, null, 123], resolved[1]);
389
+ });
390
+ });
403
391
 
404
- it('rejectsOnFirstArrayRejection', function() {
405
- var e1 = new Error('foo');
406
- var e2 = new Error('bar');
407
- var aPromise = promise.fulfilled([
408
- createRejectedPromise(e1),
409
- createRejectedPromise(e2)
410
- ]);
411
-
412
- return promise.fullyResolved(aPromise)
413
- .then(assert.fail, function(error) {
414
- assert.strictEqual(e1, error);
415
- });
416
- });
392
+ it('promiseResolvesToArrayWithPromises', function() {
393
+ var nestedPromise = Promise.resolve(123);
394
+ var aPromise = Promise.resolve([true, nestedPromise]);
395
+ return promise.fullyResolved(aPromise)
396
+ .then(function(resolved) {
397
+ assert.deepEqual([true, 123], resolved);
398
+ });
399
+ });
417
400
 
418
- it('rejectsIfNestedArrayPromiseRejects', function() {
419
- var aPromise = promise.fulfilled([
420
- promise.fulfilled([
421
- createRejectedPromise(new StubError)
422
- ])
423
- ]);
401
+ it('rejectsIfArrayPromiseRejects', function() {
402
+ var nestedPromise = createRejectedPromise(new StubError);
403
+ var aPromise = Promise.resolve([true, nestedPromise]);
424
404
 
425
- return promise.fullyResolved(aPromise)
426
- .then(assert.fail, assertIsStubError);
427
- });
405
+ var pair = callbackPair(null, assertIsStubError);
406
+ return promise.fullyResolved(aPromise)
407
+ .then(assert.fail, assertIsStubError);
408
+ });
428
409
 
429
- it('simpleHash', function() {
430
- var hash = {'a': 123};
431
- return promise.fullyResolved(hash)
432
- .then(function(resolved) {
433
- assert.strictEqual(hash, resolved);
434
- assert.deepEqual(hash, {'a': 123});
435
- });
436
- });
410
+ it('rejectsOnFirstArrayRejection', function() {
411
+ var e1 = new Error('foo');
412
+ var e2 = new Error('bar');
413
+ var aPromise = Promise.resolve([
414
+ createRejectedPromise(e1),
415
+ createRejectedPromise(e2)
416
+ ]);
417
+
418
+ return promise.fullyResolved(aPromise)
419
+ .then(assert.fail, function(error) {
420
+ assert.strictEqual(e1, error);
421
+ });
422
+ });
437
423
 
438
- it('nestedHash', function() {
439
- var nestedHash = {'foo':'bar'};
440
- var hash = {'a': 123, 'b': nestedHash};
424
+ it('rejectsIfNestedArrayPromiseRejects', function() {
425
+ var aPromise = Promise.resolve([
426
+ Promise.resolve([
427
+ createRejectedPromise(new StubError)
428
+ ])
429
+ ]);
441
430
 
442
- return promise.fullyResolved(hash)
443
- .then(function(resolved) {
444
- assert.strictEqual(hash, resolved);
445
- assert.deepEqual({'a': 123, 'b': {'foo': 'bar'}}, resolved);
446
- assert.strictEqual(nestedHash, resolved['b']);
447
- });
448
- });
431
+ return promise.fullyResolved(aPromise)
432
+ .then(assert.fail, assertIsStubError);
433
+ });
449
434
 
450
- it('promiseResolvesToSimpleHash', function() {
451
- var hash = {'a': 123};
452
- var aPromise = promise.fulfilled(hash);
435
+ it('simpleHash', function() {
436
+ var hash = {'a': 123};
437
+ return promise.fullyResolved(hash)
438
+ .then(function(resolved) {
439
+ assert.strictEqual(hash, resolved);
440
+ assert.deepEqual(hash, {'a': 123});
441
+ });
442
+ });
453
443
 
454
- return promise.fullyResolved(aPromise)
455
- .then((resolved) => assert.strictEqual(hash, resolved));
456
- });
444
+ it('nestedHash', function() {
445
+ var nestedHash = {'foo':'bar'};
446
+ var hash = {'a': 123, 'b': nestedHash};
457
447
 
458
- it('promiseResolvesToNestedHash', function() {
459
- var nestedHash = {'foo':'bar'};
460
- var hash = {'a': 123, 'b': nestedHash};
461
- var aPromise = promise.fulfilled(hash);
448
+ return promise.fullyResolved(hash)
449
+ .then(function(resolved) {
450
+ assert.strictEqual(hash, resolved);
451
+ assert.deepEqual({'a': 123, 'b': {'foo': 'bar'}}, resolved);
452
+ assert.strictEqual(nestedHash, resolved['b']);
453
+ });
454
+ });
462
455
 
463
- return promise.fullyResolved(aPromise)
464
- .then(function(resolved) {
465
- assert.strictEqual(hash, resolved);
466
- assert.strictEqual(nestedHash, resolved['b']);
467
- assert.deepEqual(hash, {'a': 123, 'b': {'foo': 'bar'}});
468
- });
469
- });
456
+ it('promiseResolvesToSimpleHash', function() {
457
+ var hash = {'a': 123};
458
+ var aPromise = Promise.resolve(hash);
470
459
 
471
- it('promiseResolvesToHashWithPromises', function() {
472
- var aPromise = promise.fulfilled({
473
- 'a': promise.fulfilled(123)
460
+ return promise.fullyResolved(aPromise)
461
+ .then((resolved) => assert.strictEqual(hash, resolved));
474
462
  });
475
463
 
476
- return promise.fullyResolved(aPromise)
477
- .then(function(resolved) {
478
- assert.deepEqual({'a': 123}, resolved);
479
- });
480
- });
464
+ it('promiseResolvesToNestedHash', function() {
465
+ var nestedHash = {'foo':'bar'};
466
+ var hash = {'a': 123, 'b': nestedHash};
467
+ var aPromise = Promise.resolve(hash);
481
468
 
482
- it('rejectsIfHashPromiseRejects', function() {
483
- var aPromise = promise.fulfilled({
484
- 'a': createRejectedPromise(new StubError)
469
+ return promise.fullyResolved(aPromise)
470
+ .then(function(resolved) {
471
+ assert.strictEqual(hash, resolved);
472
+ assert.strictEqual(nestedHash, resolved['b']);
473
+ assert.deepEqual(hash, {'a': 123, 'b': {'foo': 'bar'}});
474
+ });
485
475
  });
486
476
 
487
- return promise.fullyResolved(aPromise)
488
- .then(assert.fail, assertIsStubError);
489
- });
477
+ it('promiseResolvesToHashWithPromises', function() {
478
+ var aPromise = Promise.resolve({
479
+ 'a': Promise.resolve(123)
480
+ });
490
481
 
491
- it('rejectsIfNestedHashPromiseRejects', function() {
492
- var aPromise = promise.fulfilled({
493
- 'a': {'b': createRejectedPromise(new StubError)}
482
+ return promise.fullyResolved(aPromise)
483
+ .then(function(resolved) {
484
+ assert.deepEqual({'a': 123}, resolved);
485
+ });
494
486
  });
495
487
 
496
- return promise.fullyResolved(aPromise)
497
- .then(assert.fail, assertIsStubError);
498
- });
499
-
500
- it('instantiatedObject', function() {
501
- function Foo() {
502
- this.bar = 'baz';
503
- }
504
- var foo = new Foo;
488
+ it('rejectsIfHashPromiseRejects', function() {
489
+ var aPromise = Promise.resolve({
490
+ 'a': createRejectedPromise(new StubError)
491
+ });
505
492
 
506
- return promise.fullyResolved(foo).then(function(resolvedFoo) {
507
- assert.equal(foo, resolvedFoo);
508
- assert.ok(resolvedFoo instanceof Foo);
509
- assert.deepEqual(new Foo, resolvedFoo);
493
+ return promise.fullyResolved(aPromise)
494
+ .then(assert.fail, assertIsStubError);
510
495
  });
511
- });
512
496
 
513
- it('withEmptyArray', function() {
514
- return promise.fullyResolved([]).then(function(resolved) {
515
- assert.deepEqual([], resolved);
516
- });
517
- });
497
+ it('rejectsIfNestedHashPromiseRejects', function() {
498
+ var aPromise = Promise.resolve({
499
+ 'a': {'b': createRejectedPromise(new StubError)}
500
+ });
518
501
 
519
- it('withEmptyHash', function() {
520
- return promise.fullyResolved({}).then(function(resolved) {
521
- assert.deepEqual({}, resolved);
502
+ return promise.fullyResolved(aPromise)
503
+ .then(assert.fail, assertIsStubError);
522
504
  });
523
- });
524
505
 
525
- it('arrayWithPromisedHash', function() {
526
- var obj = {'foo': 'bar'};
527
- var array = [promise.fulfilled(obj)];
506
+ it('instantiatedObject', function() {
507
+ function Foo() {
508
+ this.bar = 'baz';
509
+ }
510
+ var foo = new Foo;
528
511
 
529
- return promise.fullyResolved(array).then(function(resolved) {
530
- assert.deepEqual(resolved, [obj]);
512
+ return promise.fullyResolved(foo).then(function(resolvedFoo) {
513
+ assert.equal(foo, resolvedFoo);
514
+ assert.ok(resolvedFoo instanceof Foo);
515
+ assert.deepEqual(new Foo, resolvedFoo);
516
+ });
531
517
  });
532
- });
533
- });
534
-
535
- describe('checkedNodeCall', function() {
536
- it('functionThrows', function() {
537
- return promise.checkedNodeCall(throwStubError)
538
- .then(assert.fail, assertIsStubError);
539
- });
540
518
 
541
- it('functionReturnsAnError', function() {
542
- return promise.checkedNodeCall(function(callback) {
543
- callback(new StubError);
544
- }).then(assert.fail, assertIsStubError);
545
- });
519
+ it('withEmptyArray', function() {
520
+ return promise.fullyResolved([]).then(function(resolved) {
521
+ assert.deepEqual([], resolved);
522
+ });
523
+ });
546
524
 
547
- it('functionReturnsSuccess', function() {
548
- var success = 'success!';
549
- return promise.checkedNodeCall(function(callback) {
550
- callback(null, success);
551
- }).then((value) => assert.equal(success, value));
552
- });
525
+ it('withEmptyHash', function() {
526
+ return promise.fullyResolved({}).then(function(resolved) {
527
+ assert.deepEqual({}, resolved);
528
+ });
529
+ });
553
530
 
554
- it('functionReturnsAndThrows', function() {
555
- var error = new Error('boom');
556
- var error2 = new Error('boom again');
557
- return promise.checkedNodeCall(function(callback) {
558
- callback(error);
559
- throw error2;
560
- }).then(assert.fail, (e) => assert.equal(error, e));
561
- });
531
+ it('arrayWithPromisedHash', function() {
532
+ var obj = {'foo': 'bar'};
533
+ var array = [Promise.resolve(obj)];
562
534
 
563
- it('functionThrowsAndReturns', function() {
564
- var error = new Error('boom');
565
- var error2 = new Error('boom again');
566
- return promise.checkedNodeCall(function(callback) {
567
- setTimeout(() => callback(error), 10);
568
- throw error2;
569
- }).then(assert.fail, (e) => assert.equal(error2, e));
535
+ return promise.fullyResolved(array).then(function(resolved) {
536
+ assert.deepEqual(resolved, [obj]);
537
+ });
538
+ });
570
539
  });
571
- });
572
540
 
573
- describe('all', function() {
574
- it('(base case)', function() {
575
- let defer = [promise.defer(), promise.defer()];
576
- var a = [
577
- 0, 1,
578
- defer[0].promise,
579
- defer[1].promise,
580
- 4, 5, 6
581
- ];
582
- delete a[5];
541
+ describe('checkedNodeCall', function() {
542
+ it('functionThrows', function() {
543
+ return promise.checkedNodeCall(throwStubError)
544
+ .then(assert.fail, assertIsStubError);
545
+ });
583
546
 
584
- var pair = callbackPair(function(value) {
585
- assert.deepEqual([0, 1, 2, 3, 4, undefined, 6], value);
547
+ it('functionReturnsAnError', function() {
548
+ return promise.checkedNodeCall(function(callback) {
549
+ callback(new StubError);
550
+ }).then(assert.fail, assertIsStubError);
586
551
  });
587
552
 
588
- var result = promise.all(a).then(pair.callback, pair.errback);
589
- pair.assertNeither();
553
+ it('functionReturnsSuccess', function() {
554
+ var success = 'success!';
555
+ return promise.checkedNodeCall(function(callback) {
556
+ callback(null, success);
557
+ }).then((value) => assert.equal(success, value));
558
+ });
590
559
 
591
- defer[0].fulfill(2);
592
- pair.assertNeither();
560
+ it('functionReturnsAndThrows', function() {
561
+ var error = new Error('boom');
562
+ var error2 = new Error('boom again');
563
+ return promise.checkedNodeCall(function(callback) {
564
+ callback(error);
565
+ throw error2;
566
+ }).then(assert.fail, (e) => assert.equal(error, e));
567
+ });
593
568
 
594
- defer[1].fulfill(3);
595
- return result.then(() => pair.assertCallback());
569
+ it('functionThrowsAndReturns', function() {
570
+ var error = new Error('boom');
571
+ var error2 = new Error('boom again');
572
+ return promise.checkedNodeCall(function(callback) {
573
+ setTimeout(() => callback(error), 10);
574
+ throw error2;
575
+ }).then(assert.fail, (e) => assert.equal(error2, e));
576
+ });
596
577
  });
597
578
 
598
- it('empty array', function() {
599
- return promise.all([]).then((a) => assert.deepEqual([], a));
600
- });
579
+ describe('all', function() {
580
+ it('(base case)', function() {
581
+ let deferredObjs = [defer(), defer()];
582
+ var a = [
583
+ 0, 1,
584
+ deferredObjs[0].promise,
585
+ deferredObjs[1].promise,
586
+ 4, 5, 6
587
+ ];
588
+ delete a[5];
601
589
 
602
- it('usesFirstRejection', function() {
603
- let defer = [promise.defer(), promise.defer()];
604
- let a = [defer[0].promise, defer[1].promise];
590
+ var pair = callbackPair(function(value) {
591
+ assert.deepEqual([0, 1, 2, 3, 4, undefined, 6], value);
592
+ });
605
593
 
606
- var result = promise.all(a).then(assert.fail, assertIsStubError);
607
- defer[1].reject(new StubError);
608
- setTimeout(() => defer[0].reject(Error('ignored')), 0);
609
- return result;
610
- });
611
- });
594
+ var result = promise.all(a).then(pair.callback, pair.errback);
595
+ pair.assertNeither();
596
+
597
+ deferredObjs[0].resolve(2);
598
+ pair.assertNeither();
612
599
 
613
- describe('map', function() {
614
- it('(base case)', function() {
615
- var a = [1, 2, 3];
616
- return promise.map(a, function(value, index, a2) {
617
- assert.equal(a, a2);
618
- assert.equal('number', typeof index, 'not a number');
619
- return value + 1;
620
- }).then(function(value) {
621
- assert.deepEqual([2, 3, 4], value);
600
+ deferredObjs[1].resolve(3);
601
+ return result.then(() => pair.assertCallback());
622
602
  });
623
- });
624
603
 
625
- it('omitsDeleted', function() {
626
- var a = [0, 1, 2, 3, 4, 5, 6];
627
- delete a[1];
628
- delete a[3];
629
- delete a[4];
630
- delete a[6];
604
+ it('empty array', function() {
605
+ return promise.all([]).then((a) => assert.deepEqual([], a));
606
+ });
631
607
 
632
- var expected = [0, 1, 4, 9, 16, 25, 36];
633
- delete expected[1];
634
- delete expected[3];
635
- delete expected[4];
636
- delete expected[6];
608
+ it('usesFirstRejection', function() {
609
+ let deferredObjs = [defer(), defer()];
610
+ let a = [deferredObjs[0].promise, deferredObjs[1].promise];
637
611
 
638
- return promise.map(a, function(value) {
639
- return value * value;
640
- }).then(function(value) {
641
- assert.deepEqual(expected, value);
612
+ var result = promise.all(a).then(assert.fail, assertIsStubError);
613
+ deferredObjs[1].reject(new StubError);
614
+ setTimeout(() => deferredObjs[0].reject(Error('ignored')), 0);
615
+ return result;
642
616
  });
643
617
  });
644
618
 
645
- it('emptyArray', function() {
646
- return promise.map([], function(value) {
647
- return value + 1;
648
- }).then(function(value) {
649
- assert.deepEqual([], value);
619
+ describe('map', function() {
620
+ it('(base case)', function() {
621
+ var a = [1, 2, 3];
622
+ return promise.map(a, function(value, index, a2) {
623
+ assert.equal(a, a2);
624
+ assert.equal('number', typeof index, 'not a number');
625
+ return value + 1;
626
+ }).then(function(value) {
627
+ assert.deepEqual([2, 3, 4], value);
628
+ });
650
629
  });
651
- });
652
630
 
653
- it('inputIsPromise', function() {
654
- var input = promise.defer();
655
- var result = promise.map(input.promise, function(value) {
656
- return value + 1;
631
+ it('omitsDeleted', function() {
632
+ var a = [0, 1, 2, 3, 4, 5, 6];
633
+ delete a[1];
634
+ delete a[3];
635
+ delete a[4];
636
+ delete a[6];
637
+
638
+ var expected = [0, 1, 4, 9, 16, 25, 36];
639
+ delete expected[1];
640
+ delete expected[3];
641
+ delete expected[4];
642
+ delete expected[6];
643
+
644
+ return promise.map(a, function(value) {
645
+ return value * value;
646
+ }).then(function(value) {
647
+ assert.deepEqual(expected, value);
648
+ });
657
649
  });
658
650
 
659
- var pair = callbackPair(function(value) {
660
- assert.deepEqual([2, 3, 4], value);
651
+ it('emptyArray', function() {
652
+ return promise.map([], function(value) {
653
+ return value + 1;
654
+ }).then(function(value) {
655
+ assert.deepEqual([], value);
656
+ });
661
657
  });
662
- result = result.then(pair.callback, pair.errback);
663
658
 
664
- setTimeout(function() {
665
- pair.assertNeither();
666
- input.fulfill([1, 2, 3]);
667
- }, 10);
659
+ it('inputIsPromise', function() {
660
+ var input = defer();
661
+ var result = promise.map(input.promise, function(value) {
662
+ return value + 1;
663
+ });
668
664
 
669
- return result;
670
- });
665
+ var pair = callbackPair(function(value) {
666
+ assert.deepEqual([2, 3, 4], value);
667
+ });
668
+ result = result.then(pair.callback, pair.errback);
671
669
 
672
- it('waitsForFunctionResultToResolve', function() {
673
- var innerResults = [
674
- promise.defer(),
675
- promise.defer()
676
- ];
670
+ setTimeout(function() {
671
+ pair.assertNeither();
672
+ input.resolve([1, 2, 3]);
673
+ }, 10);
677
674
 
678
- var result = promise.map([1, 2], function(value, index) {
679
- return innerResults[index].promise;
675
+ return result;
680
676
  });
681
677
 
682
- var pair = callbackPair(function(value) {
683
- assert.deepEqual(['a', 'b'], value);
684
- });
685
- result = result.then(pair.callback, pair.errback);
678
+ it('waitsForFunctionResultToResolve', function() {
679
+ var innerResults = [
680
+ defer(),
681
+ defer()
682
+ ];
686
683
 
687
- return NativePromise.resolve()
688
- .then(function() {
689
- pair.assertNeither();
690
- innerResults[0].fulfill('a');
691
- })
692
- .then(function() {
693
- pair.assertNeither();
694
- innerResults[1].fulfill('b');
695
- return result;
696
- })
697
- .then(pair.assertCallback);
698
- });
699
-
700
- it('rejectsPromiseIfFunctionThrows', function() {
701
- return promise.map([1], throwStubError)
702
- .then(assert.fail, assertIsStubError);
703
- });
684
+ var result = promise.map([1, 2], function(value, index) {
685
+ return innerResults[index].promise;
686
+ });
704
687
 
705
- it('rejectsPromiseIfFunctionReturnsRejectedPromise', function() {
706
- return promise.map([1], function() {
707
- return promise.rejected(new StubError);
708
- }).then(assert.fail, assertIsStubError);
709
- });
688
+ var pair = callbackPair(function(value) {
689
+ assert.deepEqual(['a', 'b'], value);
690
+ });
691
+ result = result.then(pair.callback, pair.errback);
692
+
693
+ return NativePromise.resolve()
694
+ .then(function() {
695
+ pair.assertNeither();
696
+ innerResults[0].resolve('a');
697
+ })
698
+ .then(function() {
699
+ pair.assertNeither();
700
+ innerResults[1].resolve('b');
701
+ return result;
702
+ })
703
+ .then(pair.assertCallback);
704
+ });
710
705
 
711
- it('stopsCallingFunctionIfPreviousIterationFailed', function() {
712
- var count = 0;
713
- return promise.map([1, 2, 3, 4], function() {
714
- count++;
715
- if (count == 3) {
716
- throw new StubError;
717
- }
718
- }).then(assert.fail, function(e) {
719
- assertIsStubError(e);
720
- assert.equal(3, count);
706
+ it('rejectsPromiseIfFunctionThrows', function() {
707
+ return promise.map([1], throwStubError)
708
+ .then(assert.fail, assertIsStubError);
721
709
  });
722
- });
723
710
 
724
- it('rejectsWithFirstRejectedPromise', function() {
725
- var innerResult = [
726
- promise.fulfilled(),
727
- createRejectedPromise(new StubError),
728
- createRejectedPromise(Error('should be ignored'))
729
- ];
730
- var count = 0;
731
- return promise.map([1, 2, 3, 4], function(value, index) {
732
- count += 1;
733
- return innerResult[index];
734
- }).then(assert.fail, function(e) {
735
- assertIsStubError(e);
736
- assert.equal(2, count);
711
+ it('rejectsPromiseIfFunctionReturnsRejectedPromise', function() {
712
+ return promise.map([1], function() {
713
+ return createRejectedPromise(new StubError);
714
+ }).then(assert.fail, assertIsStubError);
737
715
  });
738
- });
739
716
 
740
- it('preservesOrderWhenMapReturnsPromise', function() {
741
- var deferreds = [
742
- promise.defer(),
743
- promise.defer(),
744
- promise.defer(),
745
- promise.defer()
746
- ];
747
- var result = promise.map(deferreds, function(value) {
748
- return value.promise;
717
+ it('stopsCallingFunctionIfPreviousIterationFailed', function() {
718
+ var count = 0;
719
+ return promise.map([1, 2, 3, 4], function() {
720
+ count++;
721
+ if (count == 3) {
722
+ throw new StubError;
723
+ }
724
+ }).then(assert.fail, function(e) {
725
+ assertIsStubError(e);
726
+ assert.equal(3, count);
727
+ });
749
728
  });
750
729
 
751
- var pair = callbackPair(function(value) {
752
- assert.deepEqual([0, 1, 2, 3], value);
730
+ it('rejectsWithFirstRejectedPromise', function() {
731
+ var innerResult = [
732
+ Promise.resolve(),
733
+ createRejectedPromise(new StubError),
734
+ createRejectedPromise(Error('should be ignored'))
735
+ ];
736
+ var count = 0;
737
+ return promise.map([1, 2, 3, 4], function(value, index) {
738
+ count += 1;
739
+ return innerResult[index];
740
+ }).then(assert.fail, function(e) {
741
+ assertIsStubError(e);
742
+ assert.equal(2, count);
743
+ });
753
744
  });
754
- result = result.then(pair.callback, pair.errback);
755
745
 
756
- return NativePromise.resolve()
757
- .then(function() {
758
- pair.assertNeither();
759
- for (let i = deferreds.length; i > 0; i -= 1) {
760
- deferreds[i - 1].fulfill(i - 1);
761
- }
762
- return result;
763
- }).then(pair.assertCallback);
764
- });
765
- });
746
+ it('preservesOrderWhenMapReturnsPromise', function() {
747
+ var deferreds = [
748
+ defer(),
749
+ defer(),
750
+ defer(),
751
+ defer()
752
+ ];
753
+ var result = promise.map(deferreds, function(value) {
754
+ return value.promise;
755
+ });
766
756
 
767
- describe('filter', function() {
768
- it('basicFiltering', function() {
769
- var a = [0, 1, 2, 3];
770
- return promise.filter(a, function(val, index, a2) {
771
- assert.equal(a, a2);
772
- assert.equal('number', typeof index, 'not a number');
773
- return val > 1;
774
- }).then(function(val) {
775
- assert.deepEqual([2, 3], val);
757
+ var pair = callbackPair(function(value) {
758
+ assert.deepEqual([0, 1, 2, 3], value);
759
+ });
760
+ result = result.then(pair.callback, pair.errback);
761
+
762
+ return Promise.resolve()
763
+ .then(function() {
764
+ pair.assertNeither();
765
+ for (let i = deferreds.length; i > 0; i -= 1) {
766
+ deferreds[i - 1].resolve(i - 1);
767
+ }
768
+ return result;
769
+ }).then(pair.assertCallback);
776
770
  });
777
771
  });
778
772
 
779
- it('omitsDeleted', function() {
780
- var a = [0, 1, 2, 3, 4, 5, 6];
781
- delete a[3];
782
- delete a[4];
783
-
784
- return promise.filter(a, function(value) {
785
- return value > 1 && value < 6;
786
- }).then(function(val) {
787
- assert.deepEqual([2, 5], val);
773
+ describe('filter', function() {
774
+ it('basicFiltering', function() {
775
+ var a = [0, 1, 2, 3];
776
+ return promise.filter(a, function(val, index, a2) {
777
+ assert.equal(a, a2);
778
+ assert.equal('number', typeof index, 'not a number');
779
+ return val > 1;
780
+ }).then(function(val) {
781
+ assert.deepEqual([2, 3], val);
782
+ });
788
783
  });
789
- });
790
784
 
791
- it('preservesInputs', function() {
792
- var a = [0, 1, 2, 3];
785
+ it('omitsDeleted', function() {
786
+ var a = [0, 1, 2, 3, 4, 5, 6];
787
+ delete a[3];
788
+ delete a[4];
793
789
 
794
- return promise.filter(a, function(value, i, a2) {
795
- assert.equal(a, a2);
796
- // Even if a function modifies the input array, the original value
797
- // should be inserted into the new array.
798
- a2[i] = a2[i] - 1;
799
- return a2[i] >= 1;
800
- }).then(function(val) {
801
- assert.deepEqual([2, 3], val);
790
+ return promise.filter(a, function(value) {
791
+ return value > 1 && value < 6;
792
+ }).then(function(val) {
793
+ assert.deepEqual([2, 5], val);
794
+ });
802
795
  });
803
- });
804
796
 
805
- it('inputIsPromise', function() {
806
- var input = promise.defer();
807
- var result = promise.filter(input.promise, function(value) {
808
- return value > 1 && value < 3;
797
+ it('preservesInputs', function() {
798
+ var a = [0, 1, 2, 3];
799
+
800
+ return promise.filter(a, function(value, i, a2) {
801
+ assert.equal(a, a2);
802
+ // Even if a function modifies the input array, the original value
803
+ // should be inserted into the new array.
804
+ a2[i] = a2[i] - 1;
805
+ return a2[i] >= 1;
806
+ }).then(function(val) {
807
+ assert.deepEqual([2, 3], val);
808
+ });
809
809
  });
810
810
 
811
- var pair = callbackPair(function(value) {
812
- assert.deepEqual([2], value);
811
+ it('inputIsPromise', function() {
812
+ var input = defer();
813
+ var result = promise.filter(input.promise, function(value) {
814
+ return value > 1 && value < 3;
815
+ });
816
+
817
+ var pair = callbackPair(function(value) {
818
+ assert.deepEqual([2], value);
819
+ });
820
+ result = result.then(pair.callback, pair.errback);
821
+ return NativePromise.resolve()
822
+ .then(function() {
823
+ pair.assertNeither();
824
+ input.resolve([1, 2, 3]);
825
+ return result;
826
+ })
827
+ .then(pair.assertCallback);
813
828
  });
814
- result = result.then(pair.callback, pair.errback);
815
- return NativePromise.resolve()
816
- .then(function() {
817
- pair.assertNeither();
818
- input.fulfill([1, 2, 3]);
819
- return result;
820
- })
821
- .then(pair.assertCallback);
822
- });
823
829
 
824
- it('waitsForFunctionResultToResolve', function() {
825
- var innerResults = [
826
- promise.defer(),
827
- promise.defer()
828
- ];
830
+ it('waitsForFunctionResultToResolve', function() {
831
+ var innerResults = [
832
+ defer(),
833
+ defer()
834
+ ];
829
835
 
830
- var result = promise.filter([1, 2], function(value, index) {
831
- return innerResults[index].promise;
832
- });
836
+ var result = promise.filter([1, 2], function(value, index) {
837
+ return innerResults[index].promise;
838
+ });
833
839
 
834
- var pair = callbackPair(function(value) {
835
- assert.deepEqual([2], value);
840
+ var pair = callbackPair(function(value) {
841
+ assert.deepEqual([2], value);
842
+ });
843
+ result = result.then(pair.callback, pair.errback);
844
+ return NativePromise.resolve()
845
+ .then(function() {
846
+ pair.assertNeither();
847
+ innerResults[0].resolve(false);
848
+ })
849
+ .then(function() {
850
+ pair.assertNeither();
851
+ innerResults[1].resolve(true);
852
+ return result;
853
+ })
854
+ .then(pair.assertCallback);
836
855
  });
837
- result = result.then(pair.callback, pair.errback);
838
- return NativePromise.resolve()
839
- .then(function() {
840
- pair.assertNeither();
841
- innerResults[0].fulfill(false);
842
- })
843
- .then(function() {
844
- pair.assertNeither();
845
- innerResults[1].fulfill(true);
846
- return result;
847
- })
848
- .then(pair.assertCallback);
849
- });
850
856
 
851
- it('rejectsPromiseIfFunctionReturnsRejectedPromise', function() {
852
- return promise.filter([1], function() {
853
- return promise.rejected(new StubError);
854
- }).then(assert.fail, assertIsStubError);
855
- });
857
+ it('rejectsPromiseIfFunctionReturnsRejectedPromise', function() {
858
+ return promise.filter([1], function() {
859
+ return createRejectedPromise(new StubError);
860
+ }).then(assert.fail, assertIsStubError);
861
+ });
856
862
 
857
- it('stopsCallingFunctionIfPreviousIterationFailed', function() {
858
- var count = 0;
859
- return promise.filter([1, 2, 3, 4], function() {
860
- count++;
861
- if (count == 3) {
862
- throw new StubError;
863
- }
864
- }).then(assert.fail, function(e) {
865
- assertIsStubError(e);
866
- assert.equal(3, count);
863
+ it('stopsCallingFunctionIfPreviousIterationFailed', function() {
864
+ var count = 0;
865
+ return promise.filter([1, 2, 3, 4], function() {
866
+ count++;
867
+ if (count == 3) {
868
+ throw new StubError;
869
+ }
870
+ }).then(assert.fail, function(e) {
871
+ assertIsStubError(e);
872
+ assert.equal(3, count);
873
+ });
867
874
  });
868
- });
869
875
 
870
- it('rejectsWithFirstRejectedPromise', function() {
871
- var innerResult = [
872
- promise.fulfilled(),
873
- createRejectedPromise(new StubError),
874
- createRejectedPromise(Error('should be ignored'))
875
- ];
876
-
877
- return promise.filter([1, 2, 3, 4], function(value, index) {
878
- assert.ok(index < innerResult.length);
879
- return innerResult[index];
880
- }).then(assert.fail, assertIsStubError);
881
- });
876
+ it('rejectsWithFirstRejectedPromise', function() {
877
+ var innerResult = [
878
+ Promise.resolve(),
879
+ createRejectedPromise(new StubError),
880
+ createRejectedPromise(Error('should be ignored'))
881
+ ];
882
882
 
883
- it('preservesOrderWhenFilterReturnsPromise', function() {
884
- var deferreds = [
885
- promise.defer(),
886
- promise.defer(),
887
- promise.defer(),
888
- promise.defer()
889
- ];
890
- var result = promise.filter([0, 1, 2, 3], function(value, index) {
891
- return deferreds[index].promise;
883
+ return promise.filter([1, 2, 3, 4], function(value, index) {
884
+ assert.ok(index < innerResult.length);
885
+ return innerResult[index];
886
+ }).then(assert.fail, assertIsStubError);
892
887
  });
893
888
 
894
- var pair = callbackPair(function(value) {
895
- assert.deepEqual([1, 2], value);
896
- });
897
- result = result.then(pair.callback, pair.errback);
889
+ it('preservesOrderWhenFilterReturnsPromise', function() {
890
+ var deferreds = [
891
+ defer(),
892
+ defer(),
893
+ defer(),
894
+ defer()
895
+ ];
896
+ var result = promise.filter([0, 1, 2, 3], function(value, index) {
897
+ return deferreds[index].promise;
898
+ });
898
899
 
899
- return NativePromise.resolve()
900
- .then(function() {
901
- pair.assertNeither();
902
- for (let i = deferreds.length - 1; i >= 0; i -= 1) {
903
- deferreds[i].fulfill(i > 0 && i < 3);
904
- }
905
- return result;
906
- }).then(pair.assertCallback);
900
+ var pair = callbackPair(function(value) {
901
+ assert.deepEqual([1, 2], value);
902
+ });
903
+ result = result.then(pair.callback, pair.errback);
904
+
905
+ return NativePromise.resolve()
906
+ .then(function() {
907
+ pair.assertNeither();
908
+ for (let i = deferreds.length - 1; i >= 0; i -= 1) {
909
+ deferreds[i].resolve(i > 0 && i < 3);
910
+ }
911
+ return result;
912
+ }).then(pair.assertCallback);
913
+ });
907
914
  });
908
915
  });
909
916
 
910
- it('testAddThenableImplementation', function() {
911
- function tmp() {}
912
- assert.ok(!promise.Thenable.isImplementation(new tmp()));
913
- promise.Thenable.addImplementation(tmp);
914
- assert.ok(promise.Thenable.isImplementation(new tmp()));
915
-
916
- class tmpClass {}
917
- assert.ok(!promise.Thenable.isImplementation(new tmpClass()));
918
- promise.Thenable.addImplementation(tmpClass);
919
- assert.ok(promise.Thenable.isImplementation(new tmpClass()));
920
- });
921
-
922
- describe('testLongStackTraces', function() {
923
- beforeEach(() => promise.LONG_STACK_TRACES = false);
924
- afterEach(() => promise.LONG_STACK_TRACES = false);
917
+ enablePromiseManager(() => {
918
+ it('firesUncaughtExceptionEventIfRejectionNeverHandled', function() {
919
+ promise.rejected(new StubError);
920
+ var handler = callbackHelper(assertIsStubError);
925
921
 
926
- it('doesNotAppendStackIfFeatureDisabled', function() {
927
- promise.LONG_STACK_TRACES = false;
922
+ // so tearDown() doesn't throw
923
+ app.removeAllListeners();
924
+ app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, handler);
928
925
 
929
- var error = Error('hello');
930
- var originalStack = error.stack;
931
- return promise.rejected(error).
932
- then(fail).
933
- then(fail).
934
- then(fail).
935
- then(fail, function(e) {
936
- assert.equal(error, e);
937
- assert.equal(originalStack, e.stack);
938
- });
926
+ return NativePromise.resolve()
927
+ // Macro yield so the uncaught exception has a chance to trigger.
928
+ .then(() => new NativePromise(resolve => setTimeout(resolve, 0)))
929
+ .then(handler.assertCalled);
939
930
  });
940
931
 
941
- function getStackMessages(error) {
942
- return error.stack.split(/\n/).filter(function(line) {
943
- return /^From: /.test(line);
932
+ it('cannotResolveADeferredWithItself', function() {
933
+ var deferred = new promise.Deferred();
934
+ assert.throws(() => deferred.fulfill(deferred));
935
+ assert.throws(() => deferred.reject(deferred));
936
+ });
937
+
938
+ describe('testLongStackTraces', function() {
939
+ beforeEach(() => promise.LONG_STACK_TRACES = false);
940
+ afterEach(() => promise.LONG_STACK_TRACES = false);
941
+
942
+ it('doesNotAppendStackIfFeatureDisabled', function() {
943
+ promise.LONG_STACK_TRACES = false;
944
+
945
+ var error = Error('hello');
946
+ var originalStack = error.stack;
947
+ return promise.rejected(error).
948
+ then(fail).
949
+ then(fail).
950
+ then(fail).
951
+ then(fail, function(e) {
952
+ assert.equal(error, e);
953
+ assert.equal(originalStack, e.stack);
954
+ });
944
955
  });
945
- }
946
956
 
947
- it('appendsInitialPromiseCreation_resolverThrows', function() {
948
- promise.LONG_STACK_TRACES = true;
957
+ function getStackMessages(error) {
958
+ return error.stack.split(/\n/).filter(function(line) {
959
+ return /^From: /.test(line);
960
+ });
961
+ }
949
962
 
950
- var error = Error('hello');
951
- var originalStack = '(placeholder; will be overwritten later)';
963
+ it('appendsInitialPromiseCreation_resolverThrows', function() {
964
+ promise.LONG_STACK_TRACES = true;
952
965
 
953
- return new promise.Promise(function() {
954
- try {
955
- throw error;
956
- } catch (e) {
957
- originalStack = e.stack;
958
- throw e;
959
- }
960
- }).then(fail, function(e) {
961
- assert.strictEqual(error, e);
962
- if (typeof originalStack !== 'string') {
963
- return;
964
- }
965
- assert.notEqual(originalStack, e.stack);
966
- assert.equal(e.stack.indexOf(originalStack), 0,
967
- 'should start with original stack');
968
- assert.deepEqual(['From: ManagedPromise: new'], getStackMessages(e));
966
+ var error = Error('hello');
967
+ var originalStack = '(placeholder; will be overwritten later)';
968
+
969
+ return new promise.Promise(function() {
970
+ try {
971
+ throw error;
972
+ } catch (e) {
973
+ originalStack = e.stack;
974
+ throw e;
975
+ }
976
+ }).then(fail, function(e) {
977
+ assert.strictEqual(error, e);
978
+ if (typeof originalStack !== 'string') {
979
+ return;
980
+ }
981
+ assert.notEqual(originalStack, e.stack);
982
+ assert.equal(e.stack.indexOf(originalStack), 0,
983
+ 'should start with original stack');
984
+ assert.deepEqual(['From: ManagedPromise: new'], getStackMessages(e));
985
+ });
969
986
  });
970
- });
971
987
 
972
- it('appendsInitialPromiseCreation_rejectCalled', function() {
973
- promise.LONG_STACK_TRACES = true;
988
+ it('appendsInitialPromiseCreation_rejectCalled', function() {
989
+ promise.LONG_STACK_TRACES = true;
974
990
 
975
- var error = Error('hello');
976
- var originalStack = error.stack;
991
+ var error = Error('hello');
992
+ var originalStack = error.stack;
977
993
 
978
- return new promise.Promise(function(_, reject) {
979
- reject(error);
980
- }).then(fail, function(e) {
981
- assert.equal(error, e);
982
- if (typeof originalStack !== 'string') {
983
- return;
984
- }
985
- assert.notEqual(originalStack, e.stack);
986
- assert.equal(e.stack.indexOf(originalStack), 0,
987
- 'should start with original stack');
988
- assert.deepEqual(['From: ManagedPromise: new'], getStackMessages(e));
994
+ return new promise.Promise(function(_, reject) {
995
+ reject(error);
996
+ }).then(fail, function(e) {
997
+ assert.equal(error, e);
998
+ if (typeof originalStack !== 'string') {
999
+ return;
1000
+ }
1001
+ assert.notEqual(originalStack, e.stack);
1002
+ assert.equal(e.stack.indexOf(originalStack), 0,
1003
+ 'should start with original stack');
1004
+ assert.deepEqual(['From: ManagedPromise: new'], getStackMessages(e));
1005
+ });
989
1006
  });
990
- });
991
1007
 
992
- it('appendsEachStepToRejectionError', function() {
993
- promise.LONG_STACK_TRACES = true;
1008
+ it('appendsEachStepToRejectionError', function() {
1009
+ promise.LONG_STACK_TRACES = true;
994
1010
 
995
- var error = Error('hello');
996
- var originalStack = '(placeholder; will be overwritten later)';
1011
+ var error = Error('hello');
1012
+ var originalStack = '(placeholder; will be overwritten later)';
997
1013
 
998
- return new promise.Promise(function() {
999
- try {
1000
- throw error;
1001
- } catch (e) {
1002
- originalStack = e.stack;
1003
- throw e;
1004
- }
1005
- }).
1006
- then(fail).
1007
- catch(function(e) { throw e; }).
1008
- then(fail).
1009
- catch(function(e) { throw e; }).
1010
- then(fail, function(e) {
1011
- assert.equal(error, e);
1012
- if (typeof originalStack !== 'string') {
1013
- return;
1014
- }
1015
- assert.notEqual(originalStack, e.stack);
1016
- assert.equal(e.stack.indexOf(originalStack), 0,
1017
- 'should start with original stack');
1018
- assert.deepEqual([
1019
- 'From: ManagedPromise: new',
1020
- 'From: Promise: then',
1021
- 'From: Promise: catch',
1022
- 'From: Promise: then',
1023
- 'From: Promise: catch',
1024
- ], getStackMessages(e));
1014
+ return new promise.Promise(function() {
1015
+ try {
1016
+ throw error;
1017
+ } catch (e) {
1018
+ originalStack = e.stack;
1019
+ throw e;
1020
+ }
1021
+ }).
1022
+ then(fail).
1023
+ catch(function(e) { throw e; }).
1024
+ then(fail).
1025
+ catch(function(e) { throw e; }).
1026
+ then(fail, function(e) {
1027
+ assert.equal(error, e);
1028
+ if (typeof originalStack !== 'string') {
1029
+ return;
1030
+ }
1031
+ assert.notEqual(originalStack, e.stack);
1032
+ assert.equal(e.stack.indexOf(originalStack), 0,
1033
+ 'should start with original stack');
1034
+ assert.deepEqual([
1035
+ 'From: ManagedPromise: new',
1036
+ 'From: Promise: then',
1037
+ 'From: Promise: catch',
1038
+ 'From: Promise: then',
1039
+ 'From: Promise: catch',
1040
+ ], getStackMessages(e));
1041
+ });
1025
1042
  });
1026
- });
1027
1043
 
1028
- it('errorOccursInCallbackChain', function() {
1029
- promise.LONG_STACK_TRACES = true;
1030
-
1031
- var error = Error('hello');
1032
- var originalStack = '(placeholder; will be overwritten later)';
1033
-
1034
- return promise.fulfilled().
1035
- then(function() {}).
1036
- then(function() {}).
1037
- then(function() {
1038
- try {
1039
- throw error;
1040
- } catch (e) {
1041
- originalStack = e.stack;
1042
- throw e;
1043
- }
1044
- }).
1045
- catch(function(e) { throw e; }).
1046
- then(fail, function(e) {
1047
- assert.equal(error, e);
1048
- if (typeof originalStack !== 'string') {
1049
- return;
1050
- }
1051
- assert.notEqual(originalStack, e.stack);
1052
- assert.equal(e.stack.indexOf(originalStack), 0,
1053
- 'should start with original stack');
1054
- assert.deepEqual([
1055
- 'From: Promise: then',
1056
- 'From: Promise: catch',
1057
- ], getStackMessages(e));
1058
- });
1044
+ it('errorOccursInCallbackChain', function() {
1045
+ promise.LONG_STACK_TRACES = true;
1046
+
1047
+ var error = Error('hello');
1048
+ var originalStack = '(placeholder; will be overwritten later)';
1049
+
1050
+ return promise.fulfilled().
1051
+ then(function() {}).
1052
+ then(function() {}).
1053
+ then(function() {
1054
+ try {
1055
+ throw error;
1056
+ } catch (e) {
1057
+ originalStack = e.stack;
1058
+ throw e;
1059
+ }
1060
+ }).
1061
+ catch(function(e) { throw e; }).
1062
+ then(fail, function(e) {
1063
+ assert.equal(error, e);
1064
+ if (typeof originalStack !== 'string') {
1065
+ return;
1066
+ }
1067
+ assert.notEqual(originalStack, e.stack);
1068
+ assert.equal(e.stack.indexOf(originalStack), 0,
1069
+ 'should start with original stack');
1070
+ assert.deepEqual([
1071
+ 'From: Promise: then',
1072
+ 'From: Promise: catch',
1073
+ ], getStackMessages(e));
1074
+ });
1075
+ });
1059
1076
  });
1060
1077
  });
1078
+
1079
+ it('testAddThenableImplementation', function() {
1080
+ function tmp() {}
1081
+ assert.ok(!promise.Thenable.isImplementation(new tmp()));
1082
+ promise.Thenable.addImplementation(tmp);
1083
+ assert.ok(promise.Thenable.isImplementation(new tmp()));
1084
+
1085
+ class tmpClass {}
1086
+ assert.ok(!promise.Thenable.isImplementation(new tmpClass()));
1087
+ promise.Thenable.addImplementation(tmpClass);
1088
+ assert.ok(promise.Thenable.isImplementation(new tmpClass()));
1089
+ });
1061
1090
  });