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.
- package/dist/1plusXRtdProvider.js +1 -0
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adoceanBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bliinkBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/currency.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/impactifyBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/jixieBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/naveggIdSystem.js +1 -1
- package/dist/not-for-prod/prebid.js +112 -111
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/prebidServerBidAdapter.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/userId.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/integrationExamples/gpt/1plusXRtdProviderExample.html +112 -0
- package/modules/.submodules.json +2 -1
- package/modules/1plusXRtdProvider.js +251 -0
- package/modules/1plusXRtdProvider.md +65 -0
- package/modules/adoceanBidAdapter.js +10 -3
- package/modules/big-richmediaBidAdapter.js +3 -3
- package/modules/bliinkBidAdapter.js +120 -193
- package/modules/bliinkBidAdapter.md +2 -5
- package/modules/consumableBidAdapter.js +9 -0
- package/modules/currency.js +2 -2
- package/modules/impactifyBidAdapter.js +6 -2
- package/modules/ixBidAdapter.js +61 -14
- package/modules/ixBidAdapter.md +2 -5
- package/modules/jixieBidAdapter.js +10 -10
- package/modules/naveggIdSystem.js +1 -12
- package/modules/nextMillenniumBidAdapter.md +1 -1
- package/modules/onetagBidAdapter.js +44 -7
- package/modules/prebidServerBidAdapter/index.js +7 -0
- package/modules/rubiconBidAdapter.js +5 -0
- package/modules/seedingAllianceBidAdapter.js +3 -0
- package/modules/targetVideoBidAdapter.js +18 -0
- package/modules/userId/index.js +39 -21
- package/package.json +1 -1
- package/src/auction.js +6 -5
- package/src/consentHandler.js +11 -11
- package/src/debugging.js +5 -3
- package/src/hook.js +2 -2
- package/src/utils/promise.js +96 -21
- package/src/utils.js +3 -2
- package/test/helpers/consentData.js +2 -1
- package/test/spec/auctionmanager_spec.js +1 -6
- package/test/spec/debugging_spec.js +2 -2
- package/test/spec/modules/1plusXRtdProvider_spec.js +430 -0
- package/test/spec/modules/adoceanBidAdapter_spec.js +4 -1
- package/test/spec/modules/bliinkBidAdapter_spec.js +323 -136
- package/test/spec/modules/consumableBidAdapter_spec.js +47 -1
- package/test/spec/modules/idxIdSystem_spec.js +1 -1
- package/test/spec/modules/ixBidAdapter_spec.js +77 -2
- package/test/spec/modules/jixieBidAdapter_spec.js +8 -8
- package/test/spec/modules/onetagBidAdapter_spec.js +53 -4
- package/test/spec/modules/parrableIdSystem_spec.js +2 -1
- package/test/spec/modules/prebidServerBidAdapter_spec.js +20 -0
- package/test/spec/modules/rubiconBidAdapter_spec.js +27 -0
- package/test/spec/modules/targetVideoBidAdapter_spec.js +43 -0
- package/test/spec/modules/userId_spec.js +15 -2
- package/test/spec/unit/pbjs_api_spec.js +1 -5
- package/test/spec/unit/utils/promise_spec.js +283 -38
- package/test/helpers/syncPromise.js +0 -71
|
@@ -1,49 +1,294 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {GreedyPromise, defer} from '../../../../src/utils/promise.js';
|
|
2
2
|
|
|
3
|
-
describe('
|
|
4
|
-
function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
'
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
}
|