@forge/react
11.17.0-experimental-04cc2b911.18.0-next.0
out/hooks/__test__/useTheme.test.js~
out/hooks/__test__/useTheme.test.jsModified+34−10
Index: package/out/hooks/__test__/useTheme.test.js
===================================================================
--- package/out/hooks/__test__/useTheme.test.js
+++ package/out/hooks/__test__/useTheme.test.js
@@ -25,16 +25,30 @@
const MOCK_CONTEXT_NO_THEME = {
extension: {}
};
const themeListener = jest.fn();
+const flushUpdates = () => reconcilerTestRenderer_1.default.act(async () => {
+ await Promise.resolve();
+ await (0, utils_1.sleep)();
+});
+const emitThemeChanged = async (theme) => {
+ await reconcilerTestRenderer_1.default.act(async () => {
+ utils_1.simpleBridgeEvents.emit('FORGE_CORE_THEME_CHANGED', { theme });
+ await (0, utils_1.sleep)();
+ });
+};
// react app fragment to load useTheme hook
-const renderTest = async () => {
+const renderTest = async (options) => {
+ const flushAfterMount = options?.flushAfterMount ?? true;
const Test = () => {
const theme = (0, useTheme_1.useTheme)();
(0, react_1.useEffect)(() => themeListener(theme), [theme]);
return (0, jsx_runtime_1.jsx)(react_1.default.Fragment, {});
};
const { update } = await reconcilerTestRenderer_1.default.create((0, jsx_runtime_1.jsx)(Test, {}));
+ if (flushAfterMount) {
+ await flushUpdates();
+ }
return {
update: async () => {
await update((0, jsx_runtime_1.jsx)(Test, {}));
}
@@ -61,19 +75,21 @@
mockGetContext.mockResolvedValue(MOCK_CONTEXT_WITH_THEME);
await renderTest();
expect(themeListener).toHaveBeenCalledWith(expect.objectContaining(MOCK_THEME));
const newTheme = { colorMode: 'light', colorScheme: 'red' };
- utils_1.simpleBridgeEvents.emit('FORGE_CORE_THEME_CHANGED', { theme: newTheme });
- await (0, utils_1.sleep)();
+ await emitThemeChanged(newTheme);
expect(themeListener).toHaveBeenCalledWith(expect.objectContaining(newTheme));
});
it('does not cause re-render when theme content is the same', async () => {
mockGetContext.mockResolvedValue(MOCK_CONTEXT_WITH_THEME);
await renderTest();
- expect(themeListener).toHaveBeenCalledTimes(2); // undefined, then theme
+ expect(themeListener).toHaveBeenCalledTimes(2); // null, then theme
// Emit same theme content but different object reference
- utils_1.simpleBridgeEvents.emit('FORGE_CORE_THEME_CHANGED', {
- theme: { ...MOCK_THEME } // New object, same content
+ await reconcilerTestRenderer_1.default.act(async () => {
+ utils_1.simpleBridgeEvents.emit('FORGE_CORE_THEME_CHANGED', {
+ theme: { ...MOCK_THEME } // New object, same content
+ });
+ await (0, utils_1.sleep)();
});
// Should not trigger re-render due to isEqual check
expect(themeListener).toHaveBeenCalledTimes(2);
});
@@ -83,15 +99,23 @@
const getContextPromise = new Promise((resolve) => {
resolveGetContext = resolve;
});
mockGetContext.mockReturnValue(getContextPromise);
- const renderPromise = renderTest();
+ const renderPromise = renderTest({ flushAfterMount: false });
+ await renderPromise;
// Fire event before getContext resolves
const eventTheme = { colorMode: 'light', colorScheme: 'green' };
- utils_1.simpleBridgeEvents.emit('FORGE_CORE_THEME_CHANGED', { theme: eventTheme });
+ await reconcilerTestRenderer_1.default.act(async () => {
+ utils_1.simpleBridgeEvents.emit('FORGE_CORE_THEME_CHANGED', { theme: eventTheme });
+ await (0, utils_1.sleep)();
+ });
// Now resolve getContext
- resolveGetContext?.(MOCK_CONTEXT_WITH_THEME);
- await renderPromise;
+ await reconcilerTestRenderer_1.default.act(async () => {
+ resolveGetContext?.(MOCK_CONTEXT_WITH_THEME);
+ await getContextPromise;
+ await (0, utils_1.sleep)();
+ });
+ await flushUpdates();
// Should have the event theme, not the getContext theme
expect(themeListener).toHaveBeenCalledWith(expect.objectContaining(eventTheme));
});
});