282
expect(root).toMatchRenderedOutput('SiblingB');
283
});
284
285
+ it('sets defaultProps for modern lifecycles', async () => {
286
+ class C extends React.Component {
287
+ static defaultProps = {text: 'A'};
288
+ state = {};
289
+
290
+ static getDerivedStateFromProps(props) {
291
+ ReactTestRenderer.unstable_yield(
292
+ `getDerivedStateFromProps: ${props.text}`,
293
+ );
294
+ return null;
295
+ }
296
+
297
+ constructor(props) {
298
+ super(props);
299
+ ReactTestRenderer.unstable_yield(`constructor: ${this.props.text}`);
300
+ }
301
+
302
+ componentDidMount() {
303
+ ReactTestRenderer.unstable_yield(
304
+ `componentDidMount: ${this.props.text}`,
305
+ );
306
+ }
307
+
308
+ componentDidUpdate(prevProps) {
309
+ ReactTestRenderer.unstable_yield(
310
+ `componentDidUpdate: ${prevProps.text} -> ${this.props.text}`,
311
+ );
312
+ }
313
+
314
+ componentWillUnmount() {
315
+ ReactTestRenderer.unstable_yield(
316
+ `componentWillUnmount: ${this.props.text}`,
317
+ );
318
+ }
319
+
320
+ shouldComponentUpdate(nextProps) {
321
+ ReactTestRenderer.unstable_yield(
322
+ `shouldComponentUpdate: ${this.props.text} -> ${nextProps.text}`,
323
+ );
324
+ return true;
325
+ }
326
+
327
+ getSnapshotBeforeUpdate(prevProps) {
328
+ ReactTestRenderer.unstable_yield(
329
+ `getSnapshotBeforeUpdate: ${prevProps.text} -> ${this.props.text}`,
330
+ );
331
+ return null;
332
+ }
333
+
334
+ render() {
335
+ return <Text text={this.props.text + this.props.num} />;
336
+ }
337
+ }
338
+
339
+ const LazyClass = lazy(() => fakeImport(C));
340
+
341
+ const root = ReactTestRenderer.create(
342
+ <Suspense fallback={<Text text="Loading..." />}>
343
+ <LazyClass num={1} />
344
+ </Suspense>,
345
+ {
346
+ unstable_isConcurrent: true,
347
+ },
348
+ );
349
+
350
+ expect(root).toFlushAndYield(['Loading...']);
351
+ expect(root).toMatchRenderedOutput(null);
352
+
353
+ await Promise.resolve();
354
+
355
+ expect(root).toFlushAndYield([
356
+ 'constructor: A',
357
+ 'getDerivedStateFromProps: A',
358
+ 'A1',
359
+ 'componentDidMount: A',
360
+ ]);
361
+
362
+ root.update(
363
+ <Suspense fallback={<Text text="Loading..." />}>
364
+ <LazyClass num={2} />
365
+ </Suspense>,
366
+ );
367
+ expect(root).toFlushAndYield([
368
+ 'getDerivedStateFromProps: A',
369
+ 'shouldComponentUpdate: A -> A',
370
+ 'A2',
371
+ 'getSnapshotBeforeUpdate: A -> A',
372
+ 'componentDidUpdate: A -> A',
373
+ ]);
374
+ expect(root).toMatchRenderedOutput('A2');
375
+
376
+ root.update(
377
+ <Suspense fallback={<Text text="Loading..." />}>
378
+ <LazyClass num={3} />
379
+ </Suspense>,
380
+ );
381
+ expect(root).toFlushAndYield([
382
+ 'getDerivedStateFromProps: A',
383
+ 'shouldComponentUpdate: A -> A',
384
+ 'A3',
385
+ 'getSnapshotBeforeUpdate: A -> A',
386
+ 'componentDidUpdate: A -> A',
387
+ ]);
388
+ expect(root).toMatchRenderedOutput('A3');
389
+ });
390
+
391
+ it('sets defaultProps for legacy lifecycles', async () => {
392
+ class C extends React.Component {
393
+ static defaultProps = {text: 'A'};
394
+ state = {};
395
+
396
+ UNSAFE_componentWillMount() {
397
+ ReactTestRenderer.unstable_yield(
398
+ `UNSAFE_componentWillMount: ${this.props.text}`,
399
+ );
400
+ }
401
+
402
+ UNSAFE_componentWillUpdate(nextProps) {
403
+ ReactTestRenderer.unstable_yield(
404
+ `UNSAFE_componentWillUpdate: ${this.props.text} -> ${nextProps.text}`,
405
+ );
406
+ }
407
+
408
+ UNSAFE_componentWillReceiveProps(nextProps) {
409
+ ReactTestRenderer.unstable_yield(
410
+ `UNSAFE_componentWillReceiveProps: ${this.props.text} -> ${
411
+ nextProps.text
412
+ }`,
413
+ );
414
+ }
415
+
416
+ render() {
417
+ return <Text text={this.props.text + this.props.num} />;
418
+ }
419
+ }
420
+
421
+ const LazyClass = lazy(() => fakeImport(C));
422
+
423
+ const root = ReactTestRenderer.create(
424
+ <Suspense fallback={<Text text="Loading..." />}>
425
+ <LazyClass num={1} />
426
+ </Suspense>,
427
+ );
428
+
429
+ expect(ReactTestRenderer).toHaveYielded(['Loading...']);
430
+ expect(root).toFlushAndYield([]);
431
+ expect(root).toMatchRenderedOutput('Loading...');
432
+
433
+ await Promise.resolve();
434
+
435
+ root.update(
436
+ <Suspense fallback={<Text text="Loading..." />}>
437
+ <LazyClass num={2} />
438
+ </Suspense>,
439
+ );
440
+ expect(ReactTestRenderer).toHaveYielded([
441
+ 'UNSAFE_componentWillMount: A',
442
+ 'A1',
443
+ 'UNSAFE_componentWillReceiveProps: A -> A',
444
+ 'UNSAFE_componentWillUpdate: A -> A',
445
+ 'A2',
446
+ ]);
447
+ expect(root).toFlushAndYield([]);
448
+ expect(root).toMatchRenderedOutput('A2');
449
+
450
+ root.update(
451
+ <Suspense fallback={<Text text="Loading..." />}>
452
+ <LazyClass num={3} />
453
+ </Suspense>,
454
+ );
455
+ expect(ReactTestRenderer).toHaveYielded([
456
+ 'UNSAFE_componentWillReceiveProps: A -> A',
457
+ 'UNSAFE_componentWillUpdate: A -> A',
458
+ 'A3',
459
+ ]);
460
+ expect(root).toFlushAndYield([]);
461
+ expect(root).toMatchRenderedOutput('A3');
462
+ });
463
+
464
it('includes lazy-loaded component in warning stack', async () => {
465
const LazyFoo = lazy(() => {
466
ReactTestRenderer.unstable_yield('Started loading');