@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));
     });
 });