prebid.js 7.6.0 → 7.7.0

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 (159) hide show
  1. package/dist/1plusXRtdProvider.js +1 -0
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/adagioBidAdapter.js +1 -1
  4. package/dist/adbookpspBidAdapter.js +1 -1
  5. package/dist/adgenerationBidAdapter.js +1 -1
  6. package/dist/adoceanBidAdapter.js +1 -1
  7. package/dist/adrelevantisBidAdapter.js +1 -1
  8. package/dist/adxcgBidAdapter.js +1 -1
  9. package/dist/ajaBidAdapter.js +1 -1
  10. package/dist/amxBidAdapter.js +1 -1
  11. package/dist/amxIdSystem.js +1 -1
  12. package/dist/appierAnalyticsAdapter.js +1 -1
  13. package/dist/appnexusBidAdapter.js +1 -1
  14. package/dist/asoBidAdapter.js +1 -1
  15. package/dist/axonixBidAdapter.js +1 -1
  16. package/dist/bidglassBidAdapter.js +1 -1
  17. package/dist/big-richmediaBidAdapter.js +1 -1
  18. package/dist/bliinkBidAdapter.js +1 -1
  19. package/dist/bridgewellBidAdapter.js +1 -1
  20. package/dist/brightMountainMediaBidAdapter.js +1 -1
  21. package/dist/concertBidAdapter.js +1 -1
  22. package/dist/connectadBidAdapter.js +1 -1
  23. package/dist/consumableBidAdapter.js +1 -1
  24. package/dist/conversantBidAdapter.js +1 -1
  25. package/dist/craftBidAdapter.js +1 -1
  26. package/dist/criteoBidAdapter.js +1 -1
  27. package/dist/currency.js +1 -1
  28. package/dist/dspxBidAdapter.js +1 -1
  29. package/dist/eplanningBidAdapter.js +1 -1
  30. package/dist/finativeBidAdapter.js +1 -1
  31. package/dist/glimpseBidAdapter.js +1 -1
  32. package/dist/gmosspBidAdapter.js +1 -1
  33. package/dist/goldbachBidAdapter.js +1 -1
  34. package/dist/gridBidAdapter.js +1 -1
  35. package/dist/gridNMBidAdapter.js +1 -1
  36. package/dist/gumgumBidAdapter.js +1 -1
  37. package/dist/h12mediaBidAdapter.js +1 -1
  38. package/dist/id5IdSystem.js +1 -1
  39. package/dist/impactifyBidAdapter.js +1 -1
  40. package/dist/improvedigitalBidAdapter.js +1 -1
  41. package/dist/inmarBidAdapter.js +1 -1
  42. package/dist/insticatorBidAdapter.js +1 -1
  43. package/dist/ixBidAdapter.js +1 -1
  44. package/dist/jixieBidAdapter.js +1 -1
  45. package/dist/justpremiumBidAdapter.js +1 -1
  46. package/dist/konduitAnalyticsAdapter.js +1 -1
  47. package/dist/kueezBidAdapter.js +1 -1
  48. package/dist/lassoBidAdapter.js +1 -1
  49. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  50. package/dist/logicadBidAdapter.js +1 -1
  51. package/dist/loglyliftBidAdapter.js +1 -1
  52. package/dist/malltvAnalyticsAdapter.js +1 -1
  53. package/dist/marsmediaBidAdapter.js +1 -1
  54. package/dist/mediafuseBidAdapter.js +1 -1
  55. package/dist/mediasquareBidAdapter.js +1 -1
  56. package/dist/mgidBidAdapter.js +1 -1
  57. package/dist/minutemediaBidAdapter.js +1 -1
  58. package/dist/naveggIdSystem.js +1 -1
  59. package/dist/not-for-prod/prebid.js +112 -111
  60. package/dist/oguryBidAdapter.js +1 -1
  61. package/dist/onetagBidAdapter.js +1 -1
  62. package/dist/ooloAnalyticsAdapter.js +1 -1
  63. package/dist/outbrainBidAdapter.js +1 -1
  64. package/dist/parrableIdSystem.js +1 -1
  65. package/dist/pixfutureBidAdapter.js +1 -1
  66. package/dist/prebid-core.js +1 -1
  67. package/dist/prebidServerBidAdapter.js +1 -1
  68. package/dist/publinkIdSystem.js +1 -1
  69. package/dist/pubmaticBidAdapter.js +1 -1
  70. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  71. package/dist/pxyzBidAdapter.js +1 -1
  72. package/dist/quantcastBidAdapter.js +1 -1
  73. package/dist/readpeakBidAdapter.js +1 -1
  74. package/dist/relaidoBidAdapter.js +1 -1
  75. package/dist/rhythmoneBidAdapter.js +1 -1
  76. package/dist/riseBidAdapter.js +1 -1
  77. package/dist/rubiconAnalyticsAdapter.js +1 -1
  78. package/dist/rubiconBidAdapter.js +1 -1
  79. package/dist/seedingAllianceBidAdapter.js +1 -1
  80. package/dist/seedtagBidAdapter.js +1 -1
  81. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  82. package/dist/sharethroughBidAdapter.js +1 -1
  83. package/dist/shinezBidAdapter.js +1 -1
  84. package/dist/smaatoBidAdapter.js +1 -1
  85. package/dist/smartadserverBidAdapter.js +1 -1
  86. package/dist/smartxBidAdapter.js +1 -1
  87. package/dist/smilewantedBidAdapter.js +1 -1
  88. package/dist/sonobiBidAdapter.js +1 -1
  89. package/dist/sovrnAnalyticsAdapter.js +1 -1
  90. package/dist/sovrnBidAdapter.js +1 -1
  91. package/dist/sspBCBidAdapter.js +1 -1
  92. package/dist/sublimeBidAdapter.js +1 -1
  93. package/dist/synacormediaBidAdapter.js +1 -1
  94. package/dist/targetVideoBidAdapter.js +1 -1
  95. package/dist/teadsBidAdapter.js +1 -1
  96. package/dist/trionBidAdapter.js +1 -1
  97. package/dist/tripleliftBidAdapter.js +1 -1
  98. package/dist/ttdBidAdapter.js +1 -1
  99. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  100. package/dist/underdogmediaBidAdapter.js +1 -1
  101. package/dist/undertoneBidAdapter.js +1 -1
  102. package/dist/userId.js +1 -1
  103. package/dist/vidazooBidAdapter.js +1 -1
  104. package/dist/videobyteBidAdapter.js +1 -1
  105. package/dist/visxBidAdapter.js +1 -1
  106. package/dist/vuukleBidAdapter.js +1 -1
  107. package/dist/widespaceBidAdapter.js +1 -1
  108. package/dist/winrBidAdapter.js +1 -1
  109. package/dist/yahoosspBidAdapter.js +1 -1
  110. package/dist/yieldmoBidAdapter.js +1 -1
  111. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  112. package/integrationExamples/gpt/1plusXRtdProviderExample.html +112 -0
  113. package/modules/.submodules.json +2 -1
  114. package/modules/1plusXRtdProvider.js +251 -0
  115. package/modules/1plusXRtdProvider.md +65 -0
  116. package/modules/adoceanBidAdapter.js +10 -3
  117. package/modules/big-richmediaBidAdapter.js +3 -3
  118. package/modules/bliinkBidAdapter.js +120 -193
  119. package/modules/bliinkBidAdapter.md +2 -5
  120. package/modules/consumableBidAdapter.js +9 -0
  121. package/modules/currency.js +2 -2
  122. package/modules/impactifyBidAdapter.js +6 -2
  123. package/modules/ixBidAdapter.js +61 -14
  124. package/modules/ixBidAdapter.md +2 -5
  125. package/modules/jixieBidAdapter.js +10 -10
  126. package/modules/naveggIdSystem.js +1 -12
  127. package/modules/nextMillenniumBidAdapter.md +1 -1
  128. package/modules/onetagBidAdapter.js +44 -7
  129. package/modules/prebidServerBidAdapter/index.js +7 -0
  130. package/modules/rubiconBidAdapter.js +5 -0
  131. package/modules/seedingAllianceBidAdapter.js +3 -0
  132. package/modules/targetVideoBidAdapter.js +18 -0
  133. package/modules/userId/index.js +39 -21
  134. package/package.json +1 -1
  135. package/src/auction.js +6 -5
  136. package/src/consentHandler.js +11 -11
  137. package/src/debugging.js +5 -3
  138. package/src/hook.js +2 -2
  139. package/src/utils/promise.js +96 -21
  140. package/src/utils.js +3 -2
  141. package/test/helpers/consentData.js +2 -1
  142. package/test/spec/auctionmanager_spec.js +1 -6
  143. package/test/spec/debugging_spec.js +2 -2
  144. package/test/spec/modules/1plusXRtdProvider_spec.js +430 -0
  145. package/test/spec/modules/adoceanBidAdapter_spec.js +4 -1
  146. package/test/spec/modules/bliinkBidAdapter_spec.js +323 -136
  147. package/test/spec/modules/consumableBidAdapter_spec.js +47 -1
  148. package/test/spec/modules/idxIdSystem_spec.js +1 -1
  149. package/test/spec/modules/ixBidAdapter_spec.js +77 -2
  150. package/test/spec/modules/jixieBidAdapter_spec.js +8 -8
  151. package/test/spec/modules/onetagBidAdapter_spec.js +53 -4
  152. package/test/spec/modules/parrableIdSystem_spec.js +2 -1
  153. package/test/spec/modules/prebidServerBidAdapter_spec.js +20 -0
  154. package/test/spec/modules/rubiconBidAdapter_spec.js +27 -0
  155. package/test/spec/modules/targetVideoBidAdapter_spec.js +43 -0
  156. package/test/spec/modules/userId_spec.js +15 -2
  157. package/test/spec/unit/pbjs_api_spec.js +1 -5
  158. package/test/spec/unit/utils/promise_spec.js +283 -38
  159. package/test/helpers/syncPromise.js +0 -71
@@ -1,49 +1,294 @@
1
- import {promiseControls} from '../../../../src/utils/promise.js';
1
+ import {GreedyPromise, defer} from '../../../../src/utils/promise.js';
2
2
 
3
- describe('promiseControls', () => {
4
- function lazyControls() {
5
- // NOTE: here we are testing that calling resolve / reject works correctly regardless of whether the
6
- // browser runs promise resolvers before / after returning control to the code; e.g. with the following:
7
- //
8
- // new Promise(() => console.log('1')); console.log('2')
9
- //
10
- // it seems that the browser will output '1', then '2' - but is it always guaranteed to do so?
11
- // it's not clear from MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise)
12
- // so here we make sure it works in both cases.
13
-
14
- return promiseControls({
15
- promiseFactory: (r) => ({
16
- then: function () {
17
- const p = new Promise(r);
18
- return p.then.apply(p, arguments);
3
+ describe('GreedyPromise', () => {
4
+ it('throws when resolver is not a function', () => {
5
+ expect(() => new GreedyPromise()).to.throw();
6
+ })
7
+
8
+ Object.entries({
9
+ 'resolved': (use) => new GreedyPromise((resolve) => use(resolve)),
10
+ 'rejected': (use) => new GreedyPromise((_, reject) => use(reject))
11
+ }).forEach(([t, makePromise]) => {
12
+ it(`runs callbacks immediately when ${t}`, () => {
13
+ let cbRan = false;
14
+ const cb = () => { cbRan = true };
15
+ let resolver;
16
+ makePromise((fn) => { resolver = fn }).then(cb, cb);
17
+ resolver();
18
+ expect(cbRan).to.be.true;
19
+ })
20
+ });
21
+
22
+ describe('unhandled rejections', () => {
23
+ let unhandled, done, stop;
24
+
25
+ function reset(expectUnhandled) {
26
+ let pending = expectUnhandled;
27
+ let resolver;
28
+ unhandled.reset();
29
+ unhandled.callsFake(() => {
30
+ pending--;
31
+ if (pending === 0) {
32
+ resolver();
19
33
  }
20
34
  })
21
- })
22
- }
35
+ done = new Promise((resolve) => {
36
+ resolver = resolve;
37
+ stop = function () {
38
+ if (expectUnhandled === 0) {
39
+ resolve()
40
+ } else {
41
+ resolver = resolve;
42
+ }
43
+ }
44
+ })
45
+ }
46
+
47
+ before(() => {
48
+ unhandled = sinon.stub();
49
+ window.addEventListener('unhandledrejection', unhandled);
50
+ });
51
+
52
+ after(() => {
53
+ window.removeEventListener('unhandledrejection', unhandled);
54
+ });
55
+
56
+ function getUnhandledErrors() {
57
+ return unhandled.args.map((args) => args[0].reason);
58
+ }
59
+
60
+ Object.entries({
61
+ 'simple reject': [1, (P) => { P.reject('err'); stop() }],
62
+ 'caught reject': [0, (P) => P.reject('err').catch((e) => { stop(); return e })],
63
+ 'unhandled reject with finally': [1, (P) => P.reject('err').finally(() => 'finally')],
64
+ 'error handler that throws': [1, (P) => P.reject('err').catch((e) => { stop(); throw e })],
65
+ 'rejection handled later in the chain': [0, (P) => P.reject('err').then((v) => v).catch((e) => { stop(); return e })],
66
+ 'multiple errors in one chain': [1, (P) => P.reject('err').then((v) => v).catch((e) => e).then((v) => { stop(); return P.reject(v) })],
67
+ 'multiple errors in one chain, all handled': [0, (P) => P.reject('err').then((v) => v).catch((e) => e).then((v) => P.reject(v)).catch((e) => { stop(); return e })],
68
+ 'separate chains for rejection and handling': [1, (P) => {
69
+ const p = P.reject('err');
70
+ p.catch((e) => { stop(); return e; })
71
+ p.then((v) => v);
72
+ }],
73
+ 'separate rejections merged without handling': [2, (P) => {
74
+ const p1 = P.reject('err1');
75
+ const p2 = P.reject('err2');
76
+ p1.then(() => p2).finally(stop);
77
+ }],
78
+ 'separate rejections merged for handling': [0, (P) => {
79
+ const p1 = P.reject('err1');
80
+ const p2 = P.reject('err2');
81
+ P.all([p1, p2]).catch((e) => { stop(); return e });
82
+ }],
83
+ // eslint-disable-next-line no-throw-literal
84
+ 'exception in resolver': [1, (P) => new P(() => { stop(); throw 'err'; })],
85
+ // eslint-disable-next-line no-throw-literal
86
+ 'exception in resolver, caught': [0, (P) => new P(() => { throw 'err' }).catch((e) => { stop(); return e })],
87
+ 'errors from nested promises': [1, (P) => new P((resolve) => setTimeout(() => { resolve(P.reject('err')); stop(); }))],
88
+ 'errors from nested promises, caught': [0, (P) => new P((resolve) => setTimeout(() => resolve(P.reject('err')))).catch((e) => { stop(); return e })],
89
+ }).forEach(([t, [expectUnhandled, op]]) => {
90
+ describe(`on ${t}`, () => {
91
+ it('should match vanilla Promises', () => {
92
+ let vanillaUnhandled;
93
+ reset(expectUnhandled);
94
+ op(Promise);
95
+ return done.then(() => {
96
+ vanillaUnhandled = getUnhandledErrors();
97
+ reset(expectUnhandled);
98
+ op(GreedyPromise);
99
+ return done;
100
+ }).then(() => {
101
+ const actualUnhandled = getUnhandledErrors();
102
+ expect(actualUnhandled.length).to.eql(expectUnhandled);
103
+ expect(actualUnhandled).to.eql(vanillaUnhandled);
104
+ })
105
+ })
106
+ })
107
+ });
108
+ });
109
+
110
+ describe('idioms', () => {
111
+ let makePromise, pendingFailure, pendingSuccess;
112
+
113
+ Object.entries({
114
+ // eslint-disable-next-line no-throw-literal
115
+ 'resolver that throws': (P) => new P(() => { throw 'error' }),
116
+ 'resolver that resolves multiple times': (P) => new P((resolve) => { resolve('first'); resolve('second'); }),
117
+ 'resolver that rejects multiple times': (P) => new P((resolve, reject) => { reject('first'); reject('second') }),
118
+ 'resolver that resolves and rejects': (P) => new P((resolve, reject) => { reject('first'); resolve('second') }),
119
+ 'resolver that resolves with multiple arguments': (P) => new P((resolve) => resolve('one', 'two')),
120
+ 'resolver that rejects with multiple arguments': (P) => new P((resolve, reject) => reject('one', 'two')),
121
+ 'resolver that resolves to a promise': (P) => new P((resolve) => resolve(makePromise(P, 'val'))),
122
+ 'resolver that resolves to a promise that resolves to a promise': (P) => new P((resolve) => resolve(makePromise(P, makePromise(P, 'val')))),
123
+ 'resolver that resolves to a rejected promise': (P) => new P((resolve) => resolve(makePromise(P, 'err', true))),
124
+ 'simple .then': (P) => makePromise(P, 'value').then((v) => `${v} and then`),
125
+ 'chained .then': (P) => makePromise(P, 'value').then((v) => makePromise(P, `${v} and then`)),
126
+ '.then with error handler': (P) => makePromise(P, 'err', true).then(null, (e) => `${e} and then`),
127
+ '.then with chained error handler': (P) => makePromise(P, 'err', true).then(null, (e) => makePromise(P, `${e} and then`)),
128
+ '.then that throws': (P) => makePromise(P, 'value').then((v) => { throw v }),
129
+ '.then that throws in error handler': (P) => makePromise(P, 'err', true).then(null, (e) => { throw e }),
130
+ '.then with no args': (P) => makePromise(P, 'value').then(),
131
+ '.then that rejects': (P) => makePromise(P, 'value').then((v) => P.reject(v)),
132
+ '.then that rejects in error handler': (P) => makePromise(P, 'err', true).then(null, (err) => P.reject(err)),
133
+ '.then with no error handler on a rejection': (P) => makePromise(P, 'err', true).then((v) => `resolved ${v}`),
134
+ '.then with no success handler on a resolution': (P) => makePromise(P, 'value').then(null, (e) => `caught ${e}`),
135
+ 'simple .catch': (P) => makePromise(P, 'err', true).catch((err) => `caught ${err}`),
136
+ 'identity .catch': (P) => makePromise(P, 'err', true).catch((err) => err).then((v) => v),
137
+ '.catch that throws': (P) => makePromise(P, 'err', true).catch((err) => { throw err }),
138
+ 'chained .catch': (P) => makePromise(P, 'err', true).catch((err) => makePromise(P, err)),
139
+ 'chained .catch that rejects': (P) => makePromise(P, 'err', true).catch((err) => P.reject(`reject with ${err}`)),
140
+ 'simple .finally': (P) => {
141
+ let fval;
142
+ return makePromise(P, 'value')
143
+ .finally(() => fval = 'finally ran')
144
+ .then((val) => `${val} ${fval}`)
145
+ },
146
+ 'chained .finally': (P) => {
147
+ let fval;
148
+ return makePromise(P, 'value')
149
+ .finally(() => pendingSuccess.then(() => { fval = 'finally ran' }))
150
+ .then((val) => `${val} ${fval}`)
151
+ },
152
+ '.finally on a rejection': (P) => {
153
+ let fval;
154
+ return makePromise(P, 'error', true)
155
+ .finally(() => { fval = 'finally' })
156
+ .catch((err) => `${err} ${fval}`)
157
+ },
158
+ 'chained .finally on a rejection': (P) => {
159
+ let fval;
160
+ return makePromise(P, 'error', true)
161
+ .finally(() => pendingSuccess.then(() => { fval = 'finally' }))
162
+ .catch((err) => `${err} ${fval}`)
163
+ },
164
+ // eslint-disable-next-line no-throw-literal
165
+ '.finally that throws': (P) => makePromise(P, 'value').finally(() => { throw 'error' }),
166
+ 'chained .finally that rejects': (P) => makePromise(P, 'value').finally(() => P.reject('error')),
167
+ 'scalar Promise.resolve': (P) => P.resolve('scalar'),
168
+ 'null Promise.resolve': (P) => P.resolve(null),
169
+ 'chained Promise.resolve': (P) => P.resolve(pendingSuccess),
170
+ 'chained Promise.resolve on failure': (P) => P.resolve(pendingFailure),
171
+ 'scalar Promise.reject': (P) => P.reject('scalar'),
172
+ 'chained Promise.reject': (P) => P.reject(pendingSuccess),
173
+ 'chained Promise.reject on failure': (P) => P.reject(pendingFailure),
174
+ 'simple Promise.all': (P) => P.all([makePromise(P, 'one'), makePromise(P, 'two')]),
175
+ 'Promise.all with scalars': (P) => P.all([makePromise(P, 'one'), 'two']),
176
+ 'Promise.all with errors': (P) => P.all([makePromise(P, 'one'), makePromise(P, 'two'), makePromise(P, 'err', true)]),
177
+ 'Promise.allSettled': (P) => P.allSettled([makePromise(P, 'one', true), makePromise(P, 'two'), makePromise(P, 'three', true)]),
178
+ 'Promise.allSettled with scalars': (P) => P.allSettled([makePromise(P, 'value'), 'scalar']),
179
+ 'Promise.race that succeeds': (P) => P.race([makePromise(P, 'error', true, 10), makePromise(P, 'success')]),
180
+ 'Promise.race that fails': (P) => P.race([makePromise(P, 'success', false, 10), makePromise(P, 'error', true)]),
181
+ 'Promise.race with scalars': (P) => P.race(['scalar', makePromise(P, 'success')]),
182
+ }).forEach(([t, op]) => {
183
+ describe(t, () => {
184
+ describe('when mixed with deferrals', () => {
185
+ beforeEach(() => {
186
+ makePromise = function(ctor, value, fail = false, delay = 0) {
187
+ // eslint-disable-next-line new-cap
188
+ return new ctor((resolve, reject) => {
189
+ setTimeout(() => fail ? reject(value) : resolve(value), delay)
190
+ })
191
+ };
192
+ pendingSuccess = makePromise(Promise, 'pending result', false, 10);
193
+ pendingFailure = makePromise(Promise, 'pending failure', true, 10);
194
+ });
195
+
196
+ it(`behaves like vanilla promises`, () => {
197
+ const vanilla = op(Promise);
198
+ const greedy = op(GreedyPromise);
199
+ // note that we are not using `allSettled` & co to resolve our promises,
200
+ // to avoid transformations those methods do under the hood
201
+ const {actual = {}, expected = {}} = {};
202
+ return new Promise((resolve) => {
203
+ let pending = 2;
204
+ function collect(dest, slot) {
205
+ return function (value) {
206
+ dest[slot] = value;
207
+ pending--;
208
+ if (pending === 0) {
209
+ resolve()
210
+ }
211
+ }
212
+ }
213
+ vanilla.then(collect(expected, 'success'), collect(expected, 'failure'));
214
+ greedy.then(collect(actual, 'success'), collect(actual, 'failure'));
215
+ }).then(() => {
216
+ expect(actual).to.eql(expected);
217
+ });
218
+ });
219
+
220
+ it(`once resolved, runs callbacks immediately`, () => {
221
+ const promise = op(GreedyPromise).catch(() => null);
222
+ return promise.then(() => {
223
+ let cbRan = false;
224
+ promise.then(() => { cbRan = true });
225
+ expect(cbRan).to.be.true;
226
+ });
227
+ });
228
+ });
229
+
230
+ describe('when all promises involved are greedy', () => {
231
+ beforeEach(() => {
232
+ makePromise = function(ctor, value, fail = false, delay = 0) {
233
+ // eslint-disable-next-line new-cap
234
+ return new ctor((resolve, reject) => {
235
+ const run = () => fail ? reject(value) : resolve(value);
236
+ delay === 0 ? run() : setTimeout(run, delay);
237
+ })
238
+ };
239
+ pendingSuccess = makePromise(GreedyPromise, 'pending result');
240
+ pendingFailure = makePromise(GreedyPromise, 'pending failure', true);
241
+ });
242
+
243
+ it('resolves immediately', () => {
244
+ let cbRan = false;
245
+ op(GreedyPromise).catch(() => null).then(() => { cbRan = true });
246
+ expect(cbRan).to.be.true;
247
+ });
248
+ });
249
+ });
250
+ });
251
+ });
252
+
253
+ describe('.timeout', () => {
254
+ const timeout = GreedyPromise.timeout;
255
+
256
+ it('should resolve immediately when ms is 0', () => {
257
+ let cbRan = false;
258
+ timeout(0.0).then(() => { cbRan = true });
259
+ expect(cbRan).to.be.true;
260
+ });
261
+
262
+ it('should schedule timeout on ms > 0', (done) => {
263
+ let cbRan = false;
264
+ timeout(5).then(() => { cbRan = true });
265
+ expect(cbRan).to.be.false;
266
+ setTimeout(() => {
267
+ expect(cbRan).to.be.true;
268
+ done();
269
+ }, 10)
270
+ });
271
+ });
272
+ });
273
+
274
+ describe('promiseControls', () => {
23
275
  Object.entries({
24
276
  'resolve': (p) => p,
25
277
  'reject': (p) => p.then(() => 'wrong', (v) => v)
26
278
  }).forEach(([method, transform]) => {
27
279
  describe(method, () => {
28
- Object.entries({
29
- 'before the resolver': lazyControls,
30
- 'after the resolver': promiseControls,
31
- }).forEach(([t, controls]) => {
32
- describe(`when called ${t}`, () => {
33
- it(`should ${method} the promise`, () => {
34
- const ctl = controls();
35
- ctl[method]('result');
36
- return transform(ctl.promise).then((res) => expect(res).to.equal('result'));
37
- });
280
+ it(`should ${method} the promise`, () => {
281
+ const ctl = defer();
282
+ ctl[method]('result');
283
+ return transform(ctl.promise).then((res) => expect(res).to.equal('result'));
284
+ });
38
285
 
39
- it('should ignore calls after the first', () => {
40
- const ctl = controls();
41
- ctl[method]('result');
42
- ctl[method]('other');
43
- return transform(ctl.promise).then((res) => expect(res).to.equal('result'));
44
- });
45
- })
46
- })
47
- })
286
+ it('should ignore calls after the first', () => {
287
+ const ctl = defer();
288
+ ctl[method]('result');
289
+ ctl[method]('other');
290
+ return transform(ctl.promise).then((res) => expect(res).to.equal('result'));
291
+ });
292
+ });
48
293
  });
49
294
  });
@@ -1,71 +0,0 @@
1
- const orig = {};
2
- ['resolve', 'reject', 'all', 'race', 'allSettled'].forEach((k) => orig[k] = Promise[k].bind(Promise))
3
-
4
- // Callbacks attached through Promise.resolve(value).then(...) will usually
5
- // not execute immediately even if `value` is immediately available. This
6
- // breaks tests that were written before promises even though they are semantically still valid.
7
- // They can be made to work by making promises quasi-synchronous.
8
-
9
- export function SyncPromise(value, fail = false) {
10
- if (value instanceof SyncPromise) {
11
- return value;
12
- } else if (typeof value === 'object' && typeof value.then === 'function') {
13
- return orig.resolve(value);
14
- } else {
15
- Object.assign(this, {
16
- then: function (cb, err) {
17
- const handler = fail ? err : cb;
18
- if (handler != null) {
19
- return new SyncPromise(handler(value));
20
- } else {
21
- return this;
22
- }
23
- },
24
- catch: function (cb) {
25
- if (fail) {
26
- return new SyncPromise(cb(value))
27
- } else {
28
- return this;
29
- }
30
- },
31
- finally: function (cb) {
32
- cb();
33
- return this;
34
- },
35
- __value: fail ? {status: 'rejected', reason: value} : {status: 'fulfilled', value}
36
- })
37
- }
38
- }
39
-
40
- Object.assign(SyncPromise, {
41
- resolve: (val) => new SyncPromise(val),
42
- reject: (val) => new SyncPromise(val, true),
43
- race: (promises) => promises.find((p) => p instanceof SyncPromise) || orig.race(promises),
44
- allSettled: (promises) => {
45
- if (promises.every((p) => p instanceof SyncPromise)) {
46
- return new SyncPromise(promises.map((p) => p.__value))
47
- } else {
48
- return orig.allSettled(promises);
49
- }
50
- },
51
- all: (promises) => {
52
- if (promises.every((p) => p instanceof SyncPromise)) {
53
- return SyncPromise.allSettled(promises).then((result) => {
54
- const err = result.find((r) => r.status === 'rejected');
55
- if (err != null) {
56
- return new SyncPromise(err.reason, true);
57
- } else {
58
- return new SyncPromise(result.map((r) => r.value))
59
- }
60
- })
61
- } else {
62
- return orig.all(promises);
63
- }
64
- }
65
- })
66
-
67
- export function synchronizePromise(sandbox) {
68
- Object.keys(orig).forEach((k) => {
69
- sandbox.stub(window.Promise, k).callsFake(SyncPromise[k]);
70
- })
71
- }