Skip to content

Commit f7a2dab

Browse files
committed
test: count re-renders
1 parent 557f32d commit f7a2dab

File tree

2 files changed

+86
-6
lines changed

2 files changed

+86
-6
lines changed

src/integration.test.tsx

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { type FC } from 'react';
22
import { render, screen, waitFor } from '@testing-library/react';
33
import { EVENTS, UnleashClient } from 'unleash-proxy-client';
44
import FlagProvider from './FlagProvider';
@@ -31,6 +31,10 @@ const fetchMock = vi.fn(async () => {
3131
});
3232
});
3333

34+
beforeEach(() => {
35+
vi.clearAllMocks();
36+
});
37+
3438
test('should render toggles', async () => {
3539
const client = new UnleashClient({
3640
url: 'http://localhost:4242/api/frontend',
@@ -78,21 +82,20 @@ test('should render toggles', async () => {
7882
);
7983

8084
// After client initialization
81-
expect(fetchMock).toHaveBeenCalled();
82-
rerender(ui);
8385
expect(screen.getByTestId('ready')).toHaveTextContent('true');
8486
expect(screen.getByTestId('state')).toHaveTextContent('true');
8587
expect(screen.getByTestId('variant')).toHaveTextContent(
8688
'{"name":"A","payload":{"type":"string","value":"A"},"enabled":true,"feature_enabled":true}'
8789
);
90+
expect(fetchMock).toHaveBeenCalledOnce();
8891
});
8992

9093
test('should be ready from the start if bootstrapped', () => {
91-
const Component = React.memo(() => {
94+
const Component: FC = () => {
9295
const { flagsReady } = useFlagContext();
9396

9497
return <>{flagsReady ? 'ready' : ''}</>;
95-
});
98+
}
9699

97100
render(
98101
<FlagProvider
@@ -262,3 +265,80 @@ test('should resolve values before setting flagsReady', async () => {
262265
expect(renders).toBe(3);
263266
});
264267
});
268+
269+
test('should only re-render if flag changed, and not on status or context change', async () => {
270+
const client = new UnleashClient({
271+
url: 'http://localhost:4242/api/frontend',
272+
appName: 'test',
273+
clientKey: 'test',
274+
fetch: fetchMock,
275+
});
276+
let renders = 0;
277+
278+
const FlagTestComponent: FC = () => {
279+
const flag = useFlag('another-flag');
280+
renders += 1;
281+
282+
return (
283+
<div data-testid="flag">{flag.toString()}</div>
284+
);
285+
};
286+
287+
const ui = (
288+
<FlagProvider unleashClient={client}>
289+
<FlagTestComponent />
290+
</FlagProvider>
291+
);
292+
293+
render(ui);
294+
295+
// Before client initialization
296+
expect(fetchMock).not.toHaveBeenCalled();
297+
expect(screen.getByTestId('flag')).toHaveTextContent('false');
298+
expect(renders).toBe(1);
299+
300+
// Wait for client initialization
301+
await act(
302+
() =>
303+
new Promise((resolve) => {
304+
client.on(EVENTS.READY, () => {
305+
setTimeout(resolve, 1);
306+
});
307+
})
308+
);
309+
310+
expect(screen.getByTestId('flag')).toHaveTextContent('false');
311+
312+
fetchMock.mockImplementationOnce(async () => {
313+
return Promise.resolve({
314+
ok: true,
315+
status: 200,
316+
headers: new Headers({}),
317+
json: () => {
318+
return Promise.resolve({
319+
toggles: [
320+
{
321+
name: 'another-flag',
322+
enabled: true,
323+
variant: {
324+
name: 'A',
325+
payload: { type: 'string', value: 'A' },
326+
enabled: true,
327+
},
328+
},
329+
],
330+
});
331+
},
332+
});
333+
});
334+
335+
// Simulate flag update
336+
await act(() => client.updateToggles());
337+
expect(screen.getByTestId('flag')).toHaveTextContent('true');
338+
339+
await act(() => client.updateToggles());
340+
expect(screen.getByTestId('flag')).toHaveTextContent('false');
341+
342+
expect(fetchMock).toHaveBeenCalledTimes(3);
343+
expect(renders).toBe(3);
344+
});

src/useFlag.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const useFlag = (featureName: string) => {
3131
client.off('update', updateHandler);
3232
client.off('ready', readyHandler);
3333
};
34-
}, [client]);
34+
}, [client]); // TODO: test component renders with dynamic flag name
3535

3636
return flag;
3737
};

0 commit comments

Comments
 (0)