Skip to content

Commit c6e46a1

Browse files
committed
suspense test 4
1 parent b9dfb88 commit c6e46a1

File tree

1 file changed

+22
-115
lines changed

1 file changed

+22
-115
lines changed

src/__tests__/suspense.test.tsx

Lines changed: 22 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -118,40 +118,7 @@ function NestedSuspending({ promise }: { promise: Promise<unknown> }) {
118118
);
119119
}
120120

121-
testGateReact19('handles nested suspense boundaries', async () => {
122-
let resolveOuterPromise: (value: unknown) => void;
123-
const outerPromise = new Promise((resolve) => {
124-
resolveOuterPromise = resolve;
125-
});
126-
127-
await renderAsync(
128-
<React.Suspense fallback={<Text>Outer Loading...</Text>}>
129-
<NestedSuspending promise={outerPromise} />
130-
</React.Suspense>,
131-
);
132-
133-
expect(screen.getByText('Outer Loading...')).toBeOnTheScreen();
134-
expect(screen.queryByText('Inner Loading...')).not.toBeOnTheScreen();
135-
136-
// eslint-disable-next-line require-await
137-
await act(async () => resolveOuterPromise(null));
138-
139-
expect(screen.getByTestId('inner-resolved')).toBeOnTheScreen();
140-
expect(screen.queryByText('Outer Loading...')).not.toBeOnTheScreen();
141-
expect(screen.queryByText('Inner Loading...')).not.toBeOnTheScreen();
142-
});
143-
144-
function FirstSuspending({ promise }: { promise: Promise<unknown> }) {
145-
React.use(promise);
146-
return <View testID="first-resolved" />;
147-
}
148-
149-
function SecondSuspending({ promise }: { promise: Promise<unknown> }) {
150-
React.use(promise);
151-
return <View testID="second-resolved" />;
152-
}
153-
154-
testGateReact19('handles multiple suspending promises in same boundary', async () => {
121+
testGateReact19('handles multiple suspense boundaries independently', async () => {
155122
let resolvePromise1: (value: unknown) => void;
156123
let resolvePromise2: (value: unknown) => void;
157124

@@ -163,93 +130,33 @@ testGateReact19('handles multiple suspending promises in same boundary', async (
163130
});
164131

165132
await renderAsync(
166-
<React.Suspense fallback={<Text>Multiple Loading...</Text>}>
167-
<FirstSuspending promise={promise1} />
168-
<SecondSuspending promise={promise2} />
169-
</React.Suspense>,
133+
<View>
134+
<React.Suspense fallback={<Text>First Loading...</Text>}>
135+
<Suspending promise={promise1} />
136+
</React.Suspense>
137+
<React.Suspense fallback={<Text>Second Loading...</Text>}>
138+
<View testID="second-boundary">
139+
<Suspending promise={promise2} />
140+
</View>
141+
</React.Suspense>
142+
</View>
170143
);
171144

172-
expect(screen.getByText('Multiple Loading...')).toBeOnTheScreen();
173-
expect(screen.queryByTestId('first-resolved')).not.toBeOnTheScreen();
174-
expect(screen.queryByTestId('second-resolved')).not.toBeOnTheScreen();
145+
expect(screen.getByText('First Loading...')).toBeOnTheScreen();
146+
expect(screen.getByText('Second Loading...')).toBeOnTheScreen();
147+
expect(screen.queryByTestId('content')).not.toBeOnTheScreen();
148+
expect(screen.queryByTestId('second-boundary')).not.toBeOnTheScreen();
175149

176-
// Resolve first promise - should still be loading because second is pending
150+
// Resolve first promise
177151
// eslint-disable-next-line require-await
178152
await act(async () => resolvePromise1(null));
179-
expect(screen.getByText('Multiple Loading...')).toBeOnTheScreen();
180-
expect(screen.queryByTestId('first-resolved')).not.toBeOnTheScreen();
181-
expect(screen.queryByTestId('second-resolved')).not.toBeOnTheScreen();
153+
expect(screen.getByTestId('content')).toBeOnTheScreen();
154+
expect(screen.queryByText('First Loading...')).not.toBeOnTheScreen();
155+
expect(screen.getByText('Second Loading...')).toBeOnTheScreen();
182156

183-
// Resolve second promise - should now render all content
157+
// Resolve second promise
184158
// eslint-disable-next-line require-await
185159
await act(async () => resolvePromise2(null));
186-
expect(screen.getByTestId('first-resolved')).toBeOnTheScreen();
187-
expect(screen.getByTestId('second-resolved')).toBeOnTheScreen();
188-
expect(screen.queryByText('Multiple Loading...')).not.toBeOnTheScreen();
189-
});
190-
191-
function ConditionalSuspending({ shouldSuspend, promiseResolver }: { shouldSuspend: boolean; promiseResolver?: () => void }) {
192-
if (shouldSuspend) {
193-
const promise = React.useMemo(() => new Promise<void>((resolve) => {
194-
if (promiseResolver) {
195-
promiseResolver = resolve;
196-
}
197-
}), [promiseResolver]);
198-
React.use(promise);
199-
}
200-
return <View testID="conditional-content" />;
201-
}
202-
203-
testGateReact19('handles conditional suspense', async () => {
204-
const result = await renderAsync(
205-
<React.Suspense fallback={<Text>Conditional Loading...</Text>}>
206-
<ConditionalSuspending shouldSuspend={false} />
207-
</React.Suspense>,
208-
);
209-
210-
// Should render immediately when not suspending
211-
expect(screen.getByTestId('conditional-content')).toBeOnTheScreen();
212-
expect(screen.queryByText('Conditional Loading...')).not.toBeOnTheScreen();
213-
214-
// Re-render with suspense - this creates a new component that will suspend
215-
await result.rerenderAsync(
216-
<React.Suspense fallback={<Text>Conditional Loading...</Text>}>
217-
<ConditionalSuspending shouldSuspend={true} />
218-
</React.Suspense>,
219-
);
220-
221-
// Should now be suspended
222-
expect(screen.getByText('Conditional Loading...')).toBeOnTheScreen();
223-
expect(screen.queryByTestId('conditional-content')).not.toBeOnTheScreen();
224-
});
225-
226-
function SuspendingWithState() {
227-
const [isReady, setIsReady] = React.useState(false);
228-
229-
React.useEffect(() => {
230-
const timer = setTimeout(() => setIsReady(true), 100);
231-
return () => clearTimeout(timer);
232-
}, []);
233-
234-
if (!isReady) {
235-
const promise = new Promise(() => {}); // Never resolves
236-
React.use(promise);
237-
}
238-
239-
return <View testID="state-ready-content" />;
240-
}
241-
242-
testGateReact19('handles suspense with state updates', async () => {
243-
await renderAsync(
244-
<React.Suspense fallback={<Text>State Loading...</Text>}>
245-
<SuspendingWithState />
246-
</React.Suspense>,
247-
);
248-
249-
expect(screen.getByText('State Loading...')).toBeOnTheScreen();
250-
expect(screen.queryByTestId('state-ready-content')).not.toBeOnTheScreen();
251-
252-
// Wait for state update to resolve suspense
253-
expect(await screen.findByTestId('state-ready-content')).toBeOnTheScreen();
254-
expect(screen.queryByText('State Loading...')).not.toBeOnTheScreen();
160+
expect(screen.getByTestId('second-boundary')).toBeOnTheScreen();
161+
expect(screen.queryByText('Second Loading...')).not.toBeOnTheScreen();
255162
});

0 commit comments

Comments
 (0)