Skip to content

Commit 105e4fc

Browse files
Merge pull request #898 from splitio/readiness-sdk-ready-from-cache
Update tests
2 parents 3a5f390 + 5d621b1 commit 105e4fc

File tree

13 files changed

+157
-137
lines changed

13 files changed

+157
-137
lines changed

CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
11.7.1 (October 8, 2025)
2+
- Bugfix - Updated @splitsoftware/splitio-commons package to version 2.7.1, which fixes the `debug` option to support log levels when the `logger` option is used.
3+
14
11.7.0 (October 7, 2025)
25
- Added support for custom loggers: added `logger` configuration option and `factory.Logger.setLogger` method to allow the SDK to use a custom logger.
36
- Updated @splitsoftware/splitio-commons package to version 2.7.0.

package-lock.json

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@splitsoftware/splitio",
3-
"version": "11.7.0",
3+
"version": "11.7.1",
44
"description": "Split SDK",
55
"files": [
66
"README.md",
@@ -38,7 +38,7 @@
3838
"node": ">=14.0.0"
3939
},
4040
"dependencies": {
41-
"@splitsoftware/splitio-commons": "2.7.0",
41+
"@splitsoftware/splitio-commons": "2.7.9-rc.1",
4242
"bloom-filters": "^3.0.4",
4343
"ioredis": "^4.28.0",
4444
"js-yaml": "^3.13.1",

src/__tests__/browserSuites/ready-from-cache-async-wrapper.spec.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -168,20 +168,20 @@ export default function (fetchMock, assert) {
168168
t.true(Date.now() - startTime >= 400, 'It should emit SDK_READY too but after syncing with the cloud.');
169169
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
170170
});
171-
client.ready().then(() => {
171+
client.whenReady().then(() => {
172172
t.true(Date.now() - startTime >= 400, 'It should resolve ready promise after syncing with the cloud.');
173173
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
174174
});
175175
client2.on(client2.Event.SDK_READY, () => {
176176
t.true(Date.now() - startTime >= 700, 'It should emit SDK_READY too but after syncing with the cloud.');
177177
t.equal(client2.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
178178
});
179-
client2.ready().then(() => {
179+
client2.whenReady().then(() => {
180180
t.true(Date.now() - startTime >= 700, 'It should resolve ready promise after syncing with the cloud.');
181181
t.equal(client2.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
182182
});
183183
client3.on(client3.Event.SDK_READY, () => {
184-
client3.ready().then(() => {
184+
client3.whenReady().then(() => {
185185
t.true(Date.now() - startTime >= 1000, 'It should resolve ready promise after syncing with the cloud.');
186186
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
187187

@@ -196,7 +196,7 @@ export default function (fetchMock, assert) {
196196
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
197197
});
198198
client3.on(client3.Event.SDK_READY_TIMED_OUT, () => {
199-
client3.ready().catch(() => {
199+
client3.whenReady().catch(() => {
200200
t.true(Date.now() - startTime >= 850, 'It should reject ready promise before syncing memberships data with the cloud.');
201201
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with memberships data from cache.');
202202
});
@@ -280,20 +280,20 @@ export default function (fetchMock, assert) {
280280
t.true(nearlyEqual(Date.now() - startTime, CLIENT_READY_MS), 'It should emit SDK_READY after syncing with the cloud.');
281281
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
282282
});
283-
client.ready().then(() => {
283+
client.whenReady().then(() => {
284284
t.true(nearlyEqual(Date.now() - startTime, CLIENT_READY_MS), 'It should resolve ready promise after syncing with the cloud.');
285285
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
286286
});
287287
client2.on(client2.Event.SDK_READY, () => {
288288
t.true(nearlyEqual(Date.now() - startTime, CLIENT2_READY_MS), 'It should emit SDK_READY after syncing with the cloud.');
289289
t.equal(client2.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
290290
});
291-
client2.ready().then(() => {
291+
client2.whenReady().then(() => {
292292
t.true(nearlyEqual(Date.now() - startTime, CLIENT2_READY_MS), 'It should resolve ready promise after syncing with the cloud.');
293293
t.equal(client2.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
294294
});
295295
client3.on(client3.Event.SDK_READY, () => {
296-
client3.ready().then(() => {
296+
client3.whenReady().then(() => {
297297
t.true(nearlyEqual(Date.now() - startTime, CLIENT3_READY_MS), 'It should resolve ready promise after syncing with the cloud.');
298298
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
299299

@@ -310,7 +310,7 @@ export default function (fetchMock, assert) {
310310
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
311311
});
312312
client3.on(client3.Event.SDK_READY_TIMED_OUT, () => {
313-
client3.ready().catch(() => {
313+
client3.whenReady().catch(() => {
314314
t.true(Date.now() - startTime >= 850, 'It should reject ready promise before syncing memberships data with the cloud.');
315315
t.equal(client3.getTreatment('always_on'), 'control', 'It should not evaluate treatments with memberships data from cache.');
316316
});
@@ -359,7 +359,7 @@ export default function (fetchMock, assert) {
359359
t.true(client.__getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY, because clearOnInit is true');
360360
});
361361

362-
await client.ready();
362+
await client.whenReady();
363363

364364
t.true(console.log.calledWithMatch('clearOnInit was set and cache was not cleared in the last 24 hours. Cleaning up cache'), 'It should log a message about cleaning up cache');
365365

src/__tests__/browserSuites/ready-from-cache.spec.js

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -226,20 +226,20 @@ export default function (fetchMock, assert) {
226226
t.true(Date.now() - startTime >= 400, 'It should emit SDK_READY too but after syncing with the cloud.');
227227
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
228228
});
229-
client.ready().then(() => {
229+
client.whenReady().then(() => {
230230
t.true(Date.now() - startTime >= 400, 'It should resolve ready promise after syncing with the cloud.');
231231
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
232232
});
233233
client2.on(client2.Event.SDK_READY, () => {
234234
t.true(Date.now() - startTime >= 700, 'It should emit SDK_READY too but after syncing with the cloud.');
235235
t.equal(client2.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
236236
});
237-
client2.ready().then(() => {
237+
client2.whenReady().then(() => {
238238
t.true(Date.now() - startTime >= 700, 'It should resolve ready promise after syncing with the cloud.');
239239
t.equal(client2.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
240240
});
241241
client3.on(client3.Event.SDK_READY, () => {
242-
client3.ready().then(() => {
242+
client3.whenReady().then(() => {
243243
t.true(Date.now() - startTime >= 1000, 'It should resolve ready promise after syncing with the cloud.');
244244
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
245245

@@ -254,7 +254,7 @@ export default function (fetchMock, assert) {
254254
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
255255
});
256256
client3.on(client3.Event.SDK_READY_TIMED_OUT, () => {
257-
client3.ready().catch(() => {
257+
client3.whenReady().catch(() => {
258258
t.true(Date.now() - startTime >= 850, 'It should reject ready promise before syncing memberships data with the cloud.');
259259
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with memberships data from cache.');
260260
});
@@ -269,7 +269,7 @@ export default function (fetchMock, assert) {
269269
events: 'https://events.baseurl/readyFromCacheWithData3'
270270
};
271271
localStorage.clear();
272-
t.plan(12 * 2 + 5);
272+
t.plan(12 * 2 + 14);
273273

274274
fetchMock.get(testUrls.sdk + '/splitChanges?s=1.3&since=25&rbSince=-1', () => {
275275
t.equal(localStorage.getItem('readyFromCache_3.SPLITIO.split.always_on'), alwaysOnSplitInverted, 'feature flags must not be cleaned from cache');
@@ -285,8 +285,16 @@ export default function (fetchMock, assert) {
285285
return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'ms': {} }, headers: {} }), 1000); }); // Third client memberships will come after 1s
286286
});
287287
fetchMock.get(testUrls.sdk + '/memberships/nicolas4%40split.io', { 'ms': {} });
288-
fetchMock.postOnce(testUrls.events + '/testImpressions/bulk', 200);
289-
fetchMock.postOnce(testUrls.events + '/testImpressions/count', 200);
288+
fetchMock.postOnce(testUrls.events + '/testImpressions/bulk', (_, opts) => {
289+
const payload = JSON.parse(opts.body);
290+
t.equal(payload.length, 1, 'Only one flag was evaluated');
291+
t.equal(payload[0].i.length, 14, '14 impressions were queued, one per getTreatment call');
292+
t.equal(payload[0].i.filter((imp) => imp.t === 'control').length, 2, '2 impressions were queued for control (not ready from cache)');
293+
t.equal(payload[0].i.filter((imp) => imp.t === 'off').length, 4, '4 impressions were queued for off (ready from cache)');
294+
t.equal(payload[0].i.filter((imp) => imp.t === 'on').length, 8, '8 impressions were queued for on (ready)');
295+
296+
return 200;
297+
});
290298

291299
localStorage.setItem('some_user_item', 'user_item');
292300
localStorage.setItem('readyFromCache_3.SPLITIO.splits.till', 25);
@@ -301,6 +309,9 @@ export default function (fetchMock, assert) {
301309
type: 'LOCALSTORAGE',
302310
prefix: 'readyFromCache_3'
303311
},
312+
sync: {
313+
impressionsMode: 'DEBUG'
314+
},
304315
startup: {
305316
readyTimeout: 0.85
306317
},
@@ -320,6 +331,8 @@ export default function (fetchMock, assert) {
320331

321332
client.on(client.Event.SDK_READY_FROM_CACHE, () => {
322333
t.true(Date.now() - startTime < 400, 'It should emit SDK_READY_FROM_CACHE on every client if there was data in the cache and we subscribe on time. Should be considerably faster than actual readiness from the cloud.');
334+
t.false(client.__getStatus().isReady, 'It should not be ready yet');
335+
323336
t.equal(client.getTreatment('always_on'), 'off', 'It should evaluate treatments with data from cache instead of control due to Input Validation');
324337

325338
const client4 = splitio.client('nicolas4@split.io');
@@ -342,20 +355,27 @@ export default function (fetchMock, assert) {
342355
t.true(Date.now() - startTime >= 400, 'It should emit SDK_READY too but after syncing with the cloud.');
343356
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
344357
});
345-
client.ready().then(() => {
358+
client.whenReadyFromCache().then((isReady) => {
359+
t.false(isReady, 'It should be ready from cache before ready (syncing with the cloud).');
360+
t.true(Date.now() - startTime < 50, 'It should resolve ready from cache promise almost immediately.');
361+
});
362+
client.whenReady().then(() => {
346363
t.true(Date.now() - startTime >= 400, 'It should resolve ready promise after syncing with the cloud.');
347364
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
348365
});
349366
client2.on(client2.Event.SDK_READY, () => {
350367
t.true(Date.now() - startTime >= 700, 'It should emit SDK_READY too but after syncing with the cloud.');
351368
t.equal(client2.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
352369
});
353-
client2.ready().then(() => {
370+
client2.whenReadyFromCache().then((isReady) => {
371+
t.false(isReady, 'It should be ready from cache before ready (syncing with the cloud).');
372+
});
373+
client2.whenReady().then(() => {
354374
t.true(Date.now() - startTime >= 700, 'It should resolve ready promise after syncing with the cloud.');
355375
t.equal(client2.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
356376
});
357377
client3.on(client3.Event.SDK_READY, () => {
358-
client3.ready().then(() => {
378+
client3.whenReady().then(() => {
359379
t.true(Date.now() - startTime >= 1000, 'It should resolve ready promise after syncing with the cloud.');
360380
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
361381

@@ -370,7 +390,7 @@ export default function (fetchMock, assert) {
370390
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
371391
});
372392
client3.on(client3.Event.SDK_READY_TIMED_OUT, () => {
373-
client3.ready().catch(() => {
393+
client3.whenReady().catch(() => {
374394
t.true(Date.now() - startTime >= 850, 'It should reject ready promise before syncing memberships data with the cloud.');
375395
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with memberships data from cache.');
376396
});
@@ -452,20 +472,24 @@ export default function (fetchMock, assert) {
452472
t.true(nearlyEqual(Date.now() - startTime, CLIENT_READY_MS), 'It should emit SDK_READY after syncing with the cloud.');
453473
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
454474
});
455-
client.ready().then(() => {
475+
client.whenReadyFromCache().then((isReady) => {
476+
t.true(isReady, 'It should be ready from cache and ready.');
477+
t.true(nearlyEqual(Date.now() - startTime, CLIENT_READY_MS), 'It should resolve ready from cache promise after syncing with the cloud.');
478+
});
479+
client.whenReady().then(() => {
456480
t.true(nearlyEqual(Date.now() - startTime, CLIENT_READY_MS), 'It should resolve ready promise after syncing with the cloud.');
457481
t.equal(client.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
458482
});
459483
client2.on(client2.Event.SDK_READY, () => {
460484
t.true(nearlyEqual(Date.now() - startTime, CLIENT2_READY_MS), 'It should emit SDK_READY after syncing with the cloud.');
461485
t.equal(client2.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
462486
});
463-
client2.ready().then(() => {
487+
client2.whenReady().then(() => {
464488
t.true(nearlyEqual(Date.now() - startTime, CLIENT2_READY_MS), 'It should resolve ready promise after syncing with the cloud.');
465489
t.equal(client2.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
466490
});
467491
client3.on(client3.Event.SDK_READY, () => {
468-
client3.ready().then(() => {
492+
client3.whenReady().then(() => {
469493
t.true(nearlyEqual(Date.now() - startTime, CLIENT3_READY_MS), 'It should resolve ready promise after syncing with the cloud.');
470494
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
471495

@@ -482,7 +506,7 @@ export default function (fetchMock, assert) {
482506
t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with updated data after syncing with the cloud.');
483507
});
484508
client3.on(client3.Event.SDK_READY_TIMED_OUT, () => {
485-
client3.ready().catch(() => {
509+
client3.whenReady().catch(() => {
486510
t.true(Date.now() - startTime >= 850, 'It should reject ready promise before syncing memberships data with the cloud.');
487511
t.equal(client3.getTreatment('always_on'), 'control', 'It should not evaluate treatments with memberships data from cache.');
488512
});
@@ -898,7 +922,7 @@ export default function (fetchMock, assert) {
898922
t.true(client.__getStatus().isReady, 'Client should emit SDK_READY_FROM_CACHE alongside SDK_READY, because clearOnInit is true');
899923
});
900924

901-
await client.ready();
925+
await client.whenReady();
902926

903927
t.true(console.log.calledWithMatch('clearOnInit was set and cache was not cleared in the last 24 hours. Cleaning up cache'), 'It should log a message about cleaning up cache');
904928

0 commit comments

Comments
 (0)