Skip to content

Commit 2251ad5

Browse files
Merge branch 'FME-10595-add-evaluation-hooks' into FME-10595-add-evaluation-hooks-tests
2 parents 709a35b + c90509f commit 2251ad5

13 files changed

+65
-109
lines changed

CHANGES.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
2.6.0 (October XX, 2025)
1+
2.6.0 (October 31, 2025)
22
- Added `useTreatment`, `useTreatments`, `useTreatmentWithConfig` and `useTreatmentsWithConfig` hooks to replace the now deprecated `useSplitTreatments` hook.
3-
- Updated @splitsoftware/splitio package to version 11.7.1 that includes minor updates:
3+
- Updated @splitsoftware/splitio package to version 11.8.0 that includes minor updates:
4+
- Added new configuration for Fallback Treatments, which allows setting a treatment value and optional config to be returned in place of "control", either globally or by flag. Read more in our docs.
45
- Added support for custom loggers: added `logger` configuration option and `factory.Logger.setLogger` method to allow the SDK to use a custom logger.
6+
- Updated the SDK_READY_FROM_CACHE event to be emitted alongside the SDK_READY event if it hasn’t already been emitted.
57

68
2.5.0 (September 18, 2025)
79
- Updated @splitsoftware/splitio package to version 11.6.0 that includes minor updates:

package-lock.json

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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
},
6464
"homepage": "https://github.com/splitio/react-client#readme",
6565
"dependencies": {
66-
"@splitsoftware/splitio": "11.7.1",
66+
"@splitsoftware/splitio": "11.7.2-rc.4",
6767
"memoize-one": "^5.1.1",
6868
"shallowequal": "^1.1.0",
6969
"tslib": "^2.3.1"

src/__tests__/SplitClient.test.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ describe('SplitClient', () => {
5656
client: outerFactory.client(),
5757
isReady: true,
5858
isReadyFromCache: true,
59+
isOperational: true,
5960
lastUpdate: getStatus(outerFactory.client()).lastUpdate
6061
});
6162

@@ -141,7 +142,7 @@ describe('SplitClient', () => {
141142
expect(statusProps).toStrictEqual([false, false, true, true]);
142143
break;
143144
case 2: // Updated. Although `updateOnSdkReady` is false, status props must reflect the current status of the client.
144-
expect(statusProps).toStrictEqual([true, false, true, false]);
145+
expect(statusProps).toStrictEqual([true, true, true, false]);
145146
break;
146147
default:
147148
fail('Child must not be rerendered');
@@ -182,7 +183,7 @@ describe('SplitClient', () => {
182183
expect(statusProps).toStrictEqual([false, false, false, false]);
183184
break;
184185
case 1: // Ready
185-
expect(statusProps).toStrictEqual([true, false, true, false]); // not rerendering on SDK_TIMEOUT, but hasTimedout reflects the current state
186+
expect(statusProps).toStrictEqual([true, true, true, false]); // not rerendering on SDK_TIMEOUT, but hasTimedout reflects the current state
186187
break;
187188
default:
188189
fail('Child must not be rerendered');
@@ -214,7 +215,7 @@ describe('SplitClient', () => {
214215
count++;
215216

216217
// side effect in the render phase
217-
if (!(client as any).__getStatus().isReady) {
218+
if (!client!.getStatus().isReady) {
218219
(client as any).__emitter__.emit(Event.SDK_READY);
219220
}
220221

@@ -318,11 +319,11 @@ describe('SplitClient', () => {
318319
break;
319320
case 4:
320321
expect(client).toBe(outerFactory.client('user3'));
321-
expect(statusProps).toStrictEqual([true, false, false, false]);
322+
expect(statusProps).toStrictEqual([true, true, false, false]);
322323
break;
323324
case 5:
324325
expect(client).toBe(outerFactory.client('user3'));
325-
expect(statusProps).toStrictEqual([true, false, false, false]);
326+
expect(statusProps).toStrictEqual([true, true, false, false]);
326327
break;
327328
default:
328329
fail('Child must not be rerendered');
@@ -501,7 +502,7 @@ describe('SplitFactoryProvider + SplitClient', () => {
501502
expect(statusProps).toStrictEqual([false, false, true, true]);
502503
break;
503504
case 2: // Updated. Although `updateOnSdkReady` is false, status props must reflect the current status of the client.
504-
expect(statusProps).toStrictEqual([true, false, true, false]);
505+
expect(statusProps).toStrictEqual([true, true, true, false]);
505506
break;
506507
default:
507508
fail('Child must not be rerendered');
@@ -542,7 +543,7 @@ describe('SplitFactoryProvider + SplitClient', () => {
542543
expect(statusProps).toStrictEqual([false, false, true, true]);
543544
break;
544545
case 2: // Updated. Although `updateOnSdkReady` is false, status props must reflect the current status of the client.
545-
expect(statusProps).toStrictEqual([true, false, true, false]);
546+
expect(statusProps).toStrictEqual([true, true, true, false]);
546547
break;
547548
default:
548549
fail('Child must not be rerendered');
@@ -578,7 +579,7 @@ describe('SplitFactoryProvider + SplitClient', () => {
578579
expect(statusProps).toStrictEqual([false, false, false, false]);
579580
break;
580581
case 1: // Ready
581-
expect(statusProps).toStrictEqual([true, false, true, false]); // not rerendering on SDK_TIMEOUT, but hasTimedout reflects the current state
582+
expect(statusProps).toStrictEqual([true, true, true, false]); // not rerendering on SDK_TIMEOUT, but hasTimedout reflects the current state
582583
break;
583584
default:
584585
fail('Child must not be rerendered');
@@ -615,7 +616,7 @@ describe('SplitFactoryProvider + SplitClient', () => {
615616
expect(statusProps).toStrictEqual([false, false, false, false]);
616617
break;
617618
case 1: // Ready
618-
expect(statusProps).toStrictEqual([true, false, true, false]); // not rerendering on SDK_TIMEOUT, but hasTimedout reflects the current state
619+
expect(statusProps).toStrictEqual([true, true, true, false]); // not rerendering on SDK_TIMEOUT, but hasTimedout reflects the current state
619620
break;
620621
default:
621622
fail('Child must not be rerendered');

src/__tests__/SplitFactoryProvider.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ describe('SplitFactoryProvider', () => {
7070
client: outerFactory.client(),
7171
isReady: true,
7272
isReadyFromCache: true,
73+
isOperational: true,
7374
lastUpdate: getStatus(outerFactory.client()).lastUpdate
7475
});
7576
return null;

src/__tests__/SplitTreatments.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ describe('SplitTreatments', () => {
6969
expect(clientMock.getTreatmentsWithConfig.mock.calls.length).toBe(1);
7070
expect(treatments).toBe(clientMock.getTreatmentsWithConfig.mock.results[0].value);
7171
expect(featureFlagNames).toBe(clientMock.getTreatmentsWithConfig.mock.calls[0][0]);
72-
expect([isReady2, isReadyFromCache, hasTimedout, isTimedout, isDestroyed, lastUpdate]).toStrictEqual([true, false, false, false, false, getStatus(outerFactory.client()).lastUpdate]);
72+
expect([isReady2, isReadyFromCache, hasTimedout, isTimedout, isDestroyed, lastUpdate]).toStrictEqual([true, true, false, false, false, getStatus(outerFactory.client()).lastUpdate]);
7373
return null;
7474
}}
7575
</SplitTreatments>

src/__tests__/testUtils/mockSplitFactory.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export function mockSdk() {
5555
}
5656

5757
const __emitter__ = new EventEmitter();
58-
__emitter__.on(Event.SDK_READY, () => { isReady = true; syncLastUpdate(); });
58+
__emitter__.on(Event.SDK_READY, () => { isReady = true; isReadyFromCache = true; syncLastUpdate(); });
5959
__emitter__.on(Event.SDK_READY_FROM_CACHE, () => { isReadyFromCache = true; syncLastUpdate(); });
6060
__emitter__.on(Event.SDK_READY_TIMED_OUT, () => { hasTimedout = true; syncLastUpdate(); });
6161
__emitter__.on(Event.SDK_UPDATE, () => { syncLastUpdate(); });
@@ -115,13 +115,13 @@ export function mockSdk() {
115115
else { __emitter__.on(Event.SDK_READY_TIMED_OUT, rej); }
116116
});
117117
});
118-
const __getStatus = () => ({
118+
const getStatus = () => ({
119119
isReady,
120120
isReadyFromCache,
121121
isTimedout: hasTimedout && !isReady,
122122
hasTimedout,
123123
isDestroyed,
124-
isOperational: (isReady || isReadyFromCache) && !isDestroyed,
124+
isOperational: isReadyFromCache && !isDestroyed,
125125
lastUpdate,
126126
});
127127
const destroy: jest.Mock = jest.fn(() => {
@@ -145,10 +145,9 @@ export function mockSdk() {
145145
setAttributes,
146146
clearAttributes,
147147
getAttributes,
148+
getStatus,
148149
// EventEmitter exposed to trigger events manually
149150
__emitter__,
150-
// Clients expose a `__getStatus` method, that is not considered part of the public API, to get client readiness status (isReady, isReadyFromCache, isOperational, hasTimedout, isDestroyed)
151-
__getStatus,
152151
// Restore the mock client to its initial NO-READY status.
153152
// Useful when you want to reuse the same mock between tests after emitting events or destroying the instance.
154153
__restore() {

src/__tests__/testUtils/utils.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ export const INITIAL_STATUS: ISplitStatus & IUpdateProps = {
123123
hasTimedout: false,
124124
lastUpdate: 0,
125125
isDestroyed: false,
126+
isOperational: false,
126127
updateOnSdkReady: true,
127128
updateOnSdkReadyFromCache: true,
128129
updateOnSdkTimedout: true,

src/__tests__/useSplitClient.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ describe('useSplitClient', () => {
207207

208208
// side effect in the render phase
209209
const client = outerFactory.client('some_user') as any;
210-
if (!client.__getStatus().isReady) client.__emitter__.emit(Event.SDK_READY);
210+
if (!client.getStatus().isReady) client.__emitter__.emit(Event.SDK_READY);
211211

212212
return null;
213213
})}
@@ -256,7 +256,7 @@ describe('useSplitClient', () => {
256256

257257
act(() => mainClient.__emitter__.emit(Event.SDK_READY)); // trigger re-render
258258
expect(rendersCount).toBe(5);
259-
expect(currentStatus).toMatchObject({ isReady: true, isReadyFromCache: false, hasTimedout: true });
259+
expect(currentStatus).toMatchObject({ isReady: true, isReadyFromCache: true, hasTimedout: true });
260260

261261
act(() => mainClient.__emitter__.emit(Event.SDK_UPDATE)); // do not trigger re-render because updateOnSdkUpdate is false
262262
expect(rendersCount).toBe(5);

src/__tests__/useSplitManager.test.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ describe('useSplitManager', () => {
4848
hasTimedout: false,
4949
isDestroyed: false,
5050
isReady: true,
51-
isReadyFromCache: false,
51+
isReadyFromCache: true,
5252
isTimedout: false,
53+
isOperational: true,
5354
lastUpdate: getStatus(outerFactory.client()).lastUpdate,
5455
});
5556
});
@@ -98,8 +99,9 @@ describe('useSplitManager', () => {
9899
hasTimedout: false,
99100
isDestroyed: false,
100101
isReady: true,
101-
isReadyFromCache: false,
102+
isReadyFromCache: true,
102103
isTimedout: false,
104+
isOperational: true,
103105
lastUpdate: getStatus(outerFactory.client()).lastUpdate,
104106
});
105107
});

0 commit comments

Comments
 (0)