Add test coverage for nested Suspense
Dan Abramov committed
Apr 26, 2019 at 20:04 UTC
d81d74b2361248471ccca6f08595000a83a8a622
2 files changed
+350
src/__tests__/__snapshots__/store-test.js.snap
+174
@@ -138,6 +138,180 @@ exports[`Store collapseNodesByDefault:false should support mount and update oper
138
139
exports[`Store collapseNodesByDefault:false should support mount and update operations: 3: unmount 1`] = ``;
140
141
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 1: third child is suspended 1`] = `
142
+[root]
143
+ ▾ <Wrapper>
144
+ <Component key="Outside">
145
+ ▾ <Suspense>
146
+ <Component key="Unrelated at Start">
147
+ ▾ <Suspense>
148
+ <Component key="Suspense 1 Content">
149
+ ▾ <Suspense>
150
+ <Component key="Suspense 2 Content">
151
+ ▾ <Suspense>
152
+ <Loading key="Suspense 3 Fallback">
153
+ <Component key="Unrelated at End">
154
+`;
155
+
156
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 2: first and third child are suspended 1`] = `
157
+[root]
158
+ ▾ <Wrapper>
159
+ <Component key="Outside">
160
+ ▾ <Suspense>
161
+ <Component key="Unrelated at Start">
162
+ ▾ <Suspense>
163
+ <Loading key="Suspense 1 Fallback">
164
+ ▾ <Suspense>
165
+ <Component key="Suspense 2 Content">
166
+ ▾ <Suspense>
167
+ <Loading key="Suspense 3 Fallback">
168
+ <Component key="Unrelated at End">
169
+`;
170
+
171
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 3: second and third child are suspended 1`] = `
172
+[root]
173
+ ▾ <Wrapper>
174
+ <Component key="Outside">
175
+ ▾ <Suspense>
176
+ <Component key="Unrelated at Start">
177
+ ▾ <Suspense>
178
+ <Component key="Suspense 1 Content">
179
+ ▾ <Suspense>
180
+ <Loading key="Suspense 2 Fallback">
181
+ ▾ <Suspense>
182
+ <Loading key="Suspense 3 Fallback">
183
+ <Component key="Unrelated at End">
184
+`;
185
+
186
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 4: first and third child are suspended 1`] = `
187
+[root]
188
+ ▾ <Wrapper>
189
+ <Component key="Outside">
190
+ ▾ <Suspense>
191
+ <Component key="Unrelated at Start">
192
+ ▾ <Suspense>
193
+ <Loading key="Suspense 1 Fallback">
194
+ ▾ <Suspense>
195
+ <Component key="Suspense 2 Content">
196
+ ▾ <Suspense>
197
+ <Loading key="Suspense 3 Fallback">
198
+ <Component key="Unrelated at End">
199
+`;
200
+
201
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 5: parent is suspended 1`] = `
202
+[root]
203
+ ▾ <Wrapper>
204
+ <Component key="Outside">
205
+ ▾ <Suspense>
206
+ <Loading key="Parent Fallback">
207
+`;
208
+
209
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 6: all children are suspended 1`] = `
210
+[root]
211
+ ▾ <Wrapper>
212
+ <Component key="Outside">
213
+ ▾ <Suspense>
214
+ <Component key="Unrelated at Start">
215
+ ▾ <Suspense>
216
+ <Loading key="Suspense 1 Fallback">
217
+ ▾ <Suspense>
218
+ <Loading key="Suspense 2 Fallback">
219
+ ▾ <Suspense>
220
+ <Loading key="Suspense 3 Fallback">
221
+ <Component key="Unrelated at End">
222
+`;
223
+
224
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 7: only third child is suspended 1`] = `
225
+[root]
226
+ ▾ <Wrapper>
227
+ <Component key="Outside">
228
+ ▾ <Suspense>
229
+ <Component key="Unrelated at Start">
230
+ ▾ <Suspense>
231
+ <Component key="Suspense 1 Content">
232
+ ▾ <Suspense>
233
+ <Component key="Suspense 2 Content">
234
+ ▾ <Suspense>
235
+ <Loading key="Suspense 3 Fallback">
236
+ <Component key="Unrelated at End">
237
+`;
238
+
239
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 8: first and third child are suspended 1`] = `
240
+[root]
241
+ ▾ <Wrapper>
242
+ <Component key="Outside">
243
+ ▾ <Suspense>
244
+ <Component key="Unrelated at Start">
245
+ ▾ <Suspense>
246
+ <Loading key="Suspense 1 Fallback">
247
+ ▾ <Suspense>
248
+ <Component key="Suspense 2 Content">
249
+ ▾ <Suspense>
250
+ <Loading key="Suspense 3 Fallback">
251
+ <Component key="Unrelated at End">
252
+`;
253
+
254
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 9: parent is suspended 1`] = `
255
+[root]
256
+ ▾ <Wrapper>
257
+ <Component key="Outside">
258
+ ▾ <Suspense>
259
+ <Loading key="Parent Fallback">
260
+`;
261
+
262
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 10: parent is suspended 1`] = `
263
+[root]
264
+ ▾ <Wrapper>
265
+ <Component key="Outside">
266
+ ▾ <Suspense>
267
+ <Loading key="Parent Fallback">
268
+`;
269
+
270
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 11: all children are suspended 1`] = `
271
+[root]
272
+ ▾ <Wrapper>
273
+ <Component key="Outside">
274
+ ▾ <Suspense>
275
+ <Component key="Unrelated at Start">
276
+ ▾ <Suspense>
277
+ <Loading key="Suspense 1 Fallback">
278
+ ▾ <Suspense>
279
+ <Loading key="Suspense 2 Fallback">
280
+ ▾ <Suspense>
281
+ <Loading key="Suspense 3 Fallback">
282
+ <Component key="Unrelated at End">
283
+`;
284
+
285
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 12: all children are suspended 1`] = `
286
+[root]
287
+ ▾ <Wrapper>
288
+ <Component key="Outside">
289
+ ▾ <Suspense>
290
+ <Component key="Unrelated at Start">
291
+ ▾ <Suspense>
292
+ <Loading key="Suspense 1 Fallback">
293
+ ▾ <Suspense>
294
+ <Loading key="Suspense 2 Fallback">
295
+ ▾ <Suspense>
296
+ <Loading key="Suspense 3 Fallback">
297
+ <Component key="Unrelated at End">
298
+`;
299
+
300
+exports[`Store collapseNodesByDefault:false should support nested Suspense nodes: 13: third child is suspended 1`] = `
301
+[root]
302
+ ▾ <Wrapper>
303
+ <Component key="Outside">
304
+ ▾ <Suspense>
305
+ <Component key="Unrelated at Start">
306
+ ▾ <Suspense>
307
+ <Component key="Suspense 1 Content">
308
+ ▾ <Suspense>
309
+ <Component key="Suspense 2 Content">
310
+ ▾ <Suspense>
311
+ <Loading key="Suspense 3 Fallback">
312
+ <Component key="Unrelated at End">
313
+`;
314
+
315
exports[`Store collapseNodesByDefault:false should support reordering of children: 1: mount 1`] = `
316
[root]
317
▾ <Root>
src/__tests__/store-test.js
+176
@@ -163,6 +163,182 @@ describe('Store', () => {
163
expect(store).toMatchSnapshot('2: resolved');
164
});
165
166
+ it('should support nested Suspense nodes', () => {
167
+ const Component = () => null;
168
+ const Loading = () => <div>Loading...</div>;
169
+ const Never = () => {
170
+ throw new Promise(() => {});
171
+ };
172
+
173
+ const Wrapper = ({
174
+ suspendFirst = false,
175
+ suspendSecond = false,
176
+ suspendParent = false,
177
+ }) => (
178
+ <React.Fragment>
179
+ <Component key="Outside" />
180
+ <React.Suspense fallback={<Loading key="Parent Fallback" />}>
181
+ <Component key="Unrelated at Start" />
182
+ <React.Suspense fallback={<Loading key="Suspense 1 Fallback" />}>
183
+ {suspendFirst ? (
184
+ <Never />
185
+ ) : (
186
+ <Component key="Suspense 1 Content" />
187
+ )}
188
+ </React.Suspense>
189
+ <React.Suspense fallback={<Loading key="Suspense 2 Fallback" />}>
190
+ {suspendSecond ? (
191
+ <Never />
192
+ ) : (
193
+ <Component key="Suspense 2 Content" />
194
+ )}
195
+ </React.Suspense>
196
+ <React.Suspense fallback={<Loading key="Suspense 3 Fallback" />}>
197
+ <Never />
198
+ </React.Suspense>
199
+ {suspendParent && <Never />}
200
+ <Component key="Unrelated at End" />
201
+ </React.Suspense>
202
+ </React.Fragment>
203
+ );
204
+
205
+ const container = document.createElement('div');
206
+ act(() =>
207
+ ReactDOM.render(
208
+ <Wrapper
209
+ suspendParent={false}
210
+ suspendFirst={false}
211
+ suspendSecond={false}
212
+ />,
213
+ container
214
+ )
215
+ );
216
+ expect(store).toMatchSnapshot('1: third child is suspended');
217
+ act(() =>
218
+ ReactDOM.render(
219
+ <Wrapper
220
+ suspendParent={false}
221
+ suspendFirst={true}
222
+ suspendSecond={false}
223
+ />,
224
+ container
225
+ )
226
+ );
227
+ expect(store).toMatchSnapshot('2: first and third child are suspended');
228
+ act(() =>
229
+ ReactDOM.render(
230
+ <Wrapper
231
+ suspendParent={false}
232
+ suspendFirst={false}
233
+ suspendSecond={true}
234
+ />,
235
+ container
236
+ )
237
+ );
238
+ expect(store).toMatchSnapshot('3: second and third child are suspended');
239
+ act(() =>
240
+ ReactDOM.render(
241
+ <Wrapper
242
+ suspendParent={false}
243
+ suspendFirst={true}
244
+ suspendSecond={false}
245
+ />,
246
+ container
247
+ )
248
+ );
249
+ expect(store).toMatchSnapshot('4: first and third child are suspended');
250
+ act(() =>
251
+ ReactDOM.render(
252
+ <Wrapper
253
+ suspendParent={true}
254
+ suspendFirst={true}
255
+ suspendSecond={false}
256
+ />,
257
+ container
258
+ )
259
+ );
260
+ expect(store).toMatchSnapshot('5: parent is suspended');
261
+ act(() =>
262
+ ReactDOM.render(
263
+ <Wrapper
264
+ suspendParent={false}
265
+ suspendFirst={true}
266
+ suspendSecond={true}
267
+ />,
268
+ container
269
+ )
270
+ );
271
+ expect(store).toMatchSnapshot('6: all children are suspended');
272
+ act(() =>
273
+ ReactDOM.render(
274
+ <Wrapper
275
+ suspendParent={false}
276
+ suspendFirst={false}
277
+ suspendSecond={false}
278
+ />,
279
+ container
280
+ )
281
+ );
282
+ expect(store).toMatchSnapshot('7: only third child is suspended');
283
+
284
+ // HACK There's only one renderer for this test
285
+ const rendererID = Object.keys(agent._rendererInterfaces)[0];
286
+ act(() =>
287
+ agent.overrideSuspense({
288
+ id: store.getElementIDAtIndex(4),
289
+ rendererID,
290
+ forceFallback: true,
291
+ })
292
+ );
293
+ expect(store).toMatchSnapshot('8: first and third child are suspended');
294
+ act(() =>
295
+ agent.overrideSuspense({
296
+ id: store.getElementIDAtIndex(2),
297
+ rendererID,
298
+ forceFallback: true,
299
+ })
300
+ );
301
+ expect(store).toMatchSnapshot('9: parent is suspended');
302
+ act(() =>
303
+ ReactDOM.render(
304
+ <Wrapper
305
+ suspendParent={false}
306
+ suspendFirst={true}
307
+ suspendSecond={true}
308
+ />,
309
+ container
310
+ )
311
+ );
312
+ expect(store).toMatchSnapshot('10: parent is suspended');
313
+ act(() =>
314
+ agent.overrideSuspense({
315
+ id: store.getElementIDAtIndex(2),
316
+ rendererID,
317
+ forceFallback: false,
318
+ })
319
+ );
320
+ expect(store).toMatchSnapshot('11: all children are suspended');
321
+ act(() =>
322
+ agent.overrideSuspense({
323
+ id: store.getElementIDAtIndex(4),
324
+ rendererID,
325
+ forceFallback: false,
326
+ })
327
+ );
328
+ expect(store).toMatchSnapshot('12: all children are suspended');
329
+ act(() =>
330
+ ReactDOM.render(
331
+ <Wrapper
332
+ suspendParent={false}
333
+ suspendFirst={false}
334
+ suspendSecond={false}
335
+ />,
336
+ container
337
+ )
338
+ );
339
+ expect(store).toMatchSnapshot('13: third child is suspended');
340
+ });
341
+
342
it('should support collapsing parts of the tree', () => {
343
const Grandparent = ({ count }) => (
344
<React.Fragment>