mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Merge pull request #180 from gaearon/suspense-more-fixes
Fix unmounting in Concurrent Mode
This commit is contained in:
@@ -1,239 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`StoreStress should handle a stress test for Suspense 1`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test for Suspense 2`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test for Suspense 3`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
<C key="c">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test for Suspense 4`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<C key="c">
|
||||
<B key="b">
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test for Suspense 5`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<C key="c">
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test for Suspense 6`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<C key="c">
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test for Suspense 7`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<C key="c">
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test for Suspense 8`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test for Suspense 9`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test for Suspense 10`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
<Suspense>
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test for Suspense 11`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<B key="b">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test for Suspense 12`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test with different tree operations: 1: abcde 1`] = `
|
||||
[root]
|
||||
▾ <Parent>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
<C key="c">
|
||||
<D key="d">
|
||||
<E key="e">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle a stress test with different tree operations: 2: abxde 1`] = `
|
||||
[root]
|
||||
▾ <Parent>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
▾ <C key="c">
|
||||
<X>
|
||||
<D key="d">
|
||||
<E key="e">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 1`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<A key="a">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 2`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<B key="b">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 3`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<C key="c">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 4`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<D key="d">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 5`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<E key="e">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 6`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<A key="a">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 7`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<B key="b">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 8`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<C key="c">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 9`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<D key="d">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 10`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<E key="e">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 11`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 12`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<B key="b">
|
||||
<A key="a">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 13`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<B key="b">
|
||||
<C key="c">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 14`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<C key="c">
|
||||
<B key="b">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 15`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<A key="a">
|
||||
<C key="c">
|
||||
`;
|
||||
|
||||
exports[`StoreStress should handle stress test with reordering 16`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<C key="c">
|
||||
<A key="a">
|
||||
`;
|
||||
@@ -0,0 +1,239 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 1`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 2`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 3`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
<C key="c">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 4`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<C key="c">
|
||||
<B key="b">
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 5`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<C key="c">
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 6`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<C key="c">
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 7`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<C key="c">
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 8`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 9`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 10`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
<Suspense>
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 11`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<B key="b">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test for Suspense (Sync Mode) 12`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test with different tree operations (Sync Mode): 1: abcde 1`] = `
|
||||
[root]
|
||||
▾ <Parent>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
<C key="c">
|
||||
<D key="d">
|
||||
<E key="e">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle a stress test with different tree operations (Sync Mode): 2: abxde 1`] = `
|
||||
[root]
|
||||
▾ <Parent>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
▾ <C key="c">
|
||||
<X>
|
||||
<D key="d">
|
||||
<E key="e">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 1`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<A key="a">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 2`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<B key="b">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 3`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<C key="c">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 4`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<D key="d">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 5`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<E key="e">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 6`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<A key="a">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 7`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<B key="b">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 8`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<C key="c">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 9`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<D key="d">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 10`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<E key="e">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 11`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 12`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<B key="b">
|
||||
<A key="a">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 13`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<B key="b">
|
||||
<C key="c">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 14`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<C key="c">
|
||||
<B key="b">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 15`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<A key="a">
|
||||
<C key="c">
|
||||
`;
|
||||
|
||||
exports[`StoreStress (Sync Mode) should handle stress test with reordering (Sync Mode) 16`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<C key="c">
|
||||
<A key="a">
|
||||
`;
|
||||
@@ -0,0 +1,239 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 1`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 2`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 3`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
<C key="c">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 4`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<C key="c">
|
||||
<B key="b">
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 5`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<C key="c">
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 6`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<C key="c">
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 7`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<C key="c">
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 8`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 9`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 10`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
<Suspense>
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 11`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<B key="b">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test for Suspense (Concurrent Mode) 12`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<X>
|
||||
▾ <Suspense>
|
||||
<A key="a">
|
||||
<Y>
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test with different tree operations (Concurrent Mode): 1: abcde 1`] = `
|
||||
[root]
|
||||
▾ <Parent>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
<C key="c">
|
||||
<D key="d">
|
||||
<E key="e">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle a stress test with different tree operations (Concurrent Mode): 2: abxde 1`] = `
|
||||
[root]
|
||||
▾ <Parent>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
▾ <C key="c">
|
||||
<X>
|
||||
<D key="d">
|
||||
<E key="e">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 1`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<A key="a">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 2`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<B key="b">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 3`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<C key="c">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 4`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<D key="d">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 5`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<E key="e">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 6`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<A key="a">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 7`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<B key="b">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 8`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<C key="c">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 9`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<D key="d">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 10`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<E key="e">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 11`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<A key="a">
|
||||
<B key="b">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 12`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<B key="b">
|
||||
<A key="a">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 13`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<B key="b">
|
||||
<C key="c">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 14`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<C key="c">
|
||||
<B key="b">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 15`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<A key="a">
|
||||
<C key="c">
|
||||
`;
|
||||
|
||||
exports[`StoreStressConcurrent should handle stress test with reordering (Concurrent Mode) 16`] = `
|
||||
[root]
|
||||
▾ <Root>
|
||||
<C key="c">
|
||||
<A key="a">
|
||||
`;
|
||||
@@ -1,6 +1,6 @@
|
||||
// @flow
|
||||
|
||||
describe('StoreStress', () => {
|
||||
describe('StoreStress (Sync Mode)', () => {
|
||||
let React;
|
||||
let ReactDOM;
|
||||
let TestUtils;
|
||||
@@ -29,7 +29,7 @@ describe('StoreStress', () => {
|
||||
|
||||
// This is a stress test for the tree mount/update/unmount traversal.
|
||||
// It renders different trees that should produce the same output.
|
||||
it('should handle a stress test with different tree operations', () => {
|
||||
it('should handle a stress test with different tree operations (Sync Mode)', () => {
|
||||
let setShowX;
|
||||
const A = () => 'a';
|
||||
const B = () => 'b';
|
||||
@@ -168,37 +168,9 @@ describe('StoreStress', () => {
|
||||
}
|
||||
act(() => ReactDOM.unmountComponentAtNode(container));
|
||||
expect(print(store)).toBe('');
|
||||
|
||||
// 7. Same as the previous step, but for Concurrent Mode.
|
||||
container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
let root = ReactDOM.unstable_createRoot(container);
|
||||
for (let i = 0; i < cases.length; i++) {
|
||||
// Verify mounting 'abcde'.
|
||||
act(() => root.render(<Parent>{cases[i]}</Parent>));
|
||||
expect(container.textContent).toMatch('abcde');
|
||||
expect(print(store)).toEqual(snapshotForABCDE);
|
||||
|
||||
// Verify switching to 'abxde'.
|
||||
act(() => {
|
||||
setShowX(true);
|
||||
});
|
||||
expect(container.textContent).toMatch('abxde');
|
||||
expect(print(store)).toBe(snapshotForABXDE);
|
||||
|
||||
// Verify switching back to 'abcde'.
|
||||
act(() => {
|
||||
setShowX(false);
|
||||
});
|
||||
expect(container.textContent).toMatch('abcde');
|
||||
expect(print(store)).toBe(snapshotForABCDE);
|
||||
// Don't unmount. Reuse the container between iterations.
|
||||
}
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
});
|
||||
|
||||
it('should handle stress test with reordering', () => {
|
||||
it('should handle stress test with reordering (Sync Mode)', () => {
|
||||
const A = () => 'a';
|
||||
const B = () => 'b';
|
||||
const C = () => 'c';
|
||||
@@ -298,7 +270,7 @@ describe('StoreStress', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should handle a stress test for Suspense', async () => {
|
||||
it('should handle a stress test for Suspense (Sync Mode)', async () => {
|
||||
const A = () => 'a';
|
||||
const B = () => 'b';
|
||||
const C = () => 'c';
|
||||
@@ -690,6 +662,5 @@ describe('StoreStress', () => {
|
||||
expect(print(store)).toBe('');
|
||||
}
|
||||
}
|
||||
// TODO: Test Concurrent Mode
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,671 @@
|
||||
// @flow
|
||||
|
||||
describe('StoreStressConcurrent', () => {
|
||||
let React;
|
||||
let ReactDOM;
|
||||
let TestUtils;
|
||||
let bridge;
|
||||
let store;
|
||||
let print;
|
||||
|
||||
const act = (callback: Function) => {
|
||||
TestUtils.act(() => {
|
||||
callback();
|
||||
});
|
||||
jest.advanceTimersByTime(1000); // Flush rendering and Suspense
|
||||
jest.runAllTimers(); // Flush Bridge operations
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
bridge = global.bridge;
|
||||
store = global.store;
|
||||
store.collapseNodesByDefault = false;
|
||||
|
||||
React = require('react');
|
||||
ReactDOM = require('react-dom');
|
||||
TestUtils = require('react-dom/test-utils');
|
||||
|
||||
print = require('./storeSerializer').print;
|
||||
});
|
||||
|
||||
// This is a stress test for the tree mount/update/unmount traversal.
|
||||
// It renders different trees that should produce the same output.
|
||||
it('should handle a stress test with different tree operations (Concurrent Mode)', () => {
|
||||
let setShowX;
|
||||
const A = () => 'a';
|
||||
const B = () => 'b';
|
||||
const C = () => {
|
||||
// We'll be manually flipping this component back and forth in the test.
|
||||
// We only do this for a single node in order to verify that DevTools
|
||||
// can handle a subtree switching alternates while other subtrees are memoized.
|
||||
let [showX, _setShowX] = React.useState(false);
|
||||
setShowX = _setShowX;
|
||||
return showX ? <X /> : 'c';
|
||||
};
|
||||
const D = () => 'd';
|
||||
const E = () => 'e';
|
||||
const X = () => 'x';
|
||||
const a = <A key="a" />;
|
||||
const b = <B key="b" />;
|
||||
const c = <C key="c" />;
|
||||
const d = <D key="d" />;
|
||||
const e = <E key="e" />;
|
||||
|
||||
function Parent({ children }) {
|
||||
return children;
|
||||
}
|
||||
|
||||
// 1. Render a normal version of [a, b, c, d, e].
|
||||
let container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
let root = ReactDOM.unstable_createRoot(container);
|
||||
act(() => root.render(<Parent>{[a, b, c, d, e]}</Parent>));
|
||||
expect(store).toMatchSnapshot('1: abcde');
|
||||
expect(container.textContent).toMatch('abcde');
|
||||
const snapshotForABCDE = print(store);
|
||||
|
||||
// 2. Render a version where <C /> renders an <X /> child instead of 'c'.
|
||||
// This is how we'll test an update to a single component.
|
||||
act(() => {
|
||||
setShowX(true);
|
||||
});
|
||||
expect(store).toMatchSnapshot('2: abxde');
|
||||
expect(container.textContent).toMatch('abxde');
|
||||
const snapshotForABXDE = print(store);
|
||||
|
||||
// 3. Verify flipping it back produces the original result.
|
||||
act(() => {
|
||||
setShowX(false);
|
||||
});
|
||||
expect(container.textContent).toMatch('abcde');
|
||||
expect(print(store)).toBe(snapshotForABCDE);
|
||||
|
||||
// 4. Clean up.
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
|
||||
// Now comes the interesting part.
|
||||
// All of these cases are equivalent to [a, b, c, d, e] in output.
|
||||
// We'll verify that DevTools produces the same snapshots for them.
|
||||
// These cases are picked so that rendering them sequentially in the same
|
||||
// container results in a combination of mounts, updates, unmounts, and reorders.
|
||||
// prettier-ignore
|
||||
let cases = [
|
||||
[a, b, c, d, e],
|
||||
[[a], b, c, d, e],
|
||||
[[a, b], c, d, e],
|
||||
[[a, b], c, [d, e]],
|
||||
[[a, b], c, [d, '', e]],
|
||||
[[a], b, c, d, [e]],
|
||||
[a, b, [[c]], d, e],
|
||||
[[a, ''], [b], [c], [d], [e]],
|
||||
[a, b, [c, [d, ['', e]]]],
|
||||
[a, b, c, d, e],
|
||||
[<div key="0">{a}</div>, b, c, d, e],
|
||||
[<div key="0">{a}{b}</div>, c, d, e],
|
||||
[<div key="0">{a}{b}</div>, c, <div key="1">{d}{e}</div>],
|
||||
[<div key="1">{a}{b}</div>, c, <div key="0">{d}{e}</div>],
|
||||
[<div key="0">{a}{b}</div>, c, <div key="1">{d}{e}</div>],
|
||||
[<div key="2">{a}{b}</div>, c, <div key="3">{d}{e}</div>],
|
||||
[<span key="0">{a}</span>, b, c, d, [e]],
|
||||
[a, b, <span key="0"><span>{c}</span></span>, d, e],
|
||||
[<div key="0">{a}</div>, [b], <span key="1">{c}</span>, [d], <div key="2">{e}</div>],
|
||||
[a, b, [c, <div key="0">{d}<span>{e}</span></div>], ''],
|
||||
[a, [[]], b, c, [d, [[]], e]],
|
||||
[[[a, b, c, d], e]],
|
||||
[a, b, c, d, e]
|
||||
];
|
||||
|
||||
// 5. Test fresh mount for each case.
|
||||
for (let i = 0; i < cases.length; i++) {
|
||||
// Ensure fresh mount.
|
||||
container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
root = ReactDOM.unstable_createRoot(container);
|
||||
|
||||
// Verify mounting 'abcde'.
|
||||
act(() => root.render(<Parent>{cases[i]}</Parent>));
|
||||
expect(container.textContent).toMatch('abcde');
|
||||
expect(print(store)).toEqual(snapshotForABCDE);
|
||||
|
||||
// Verify switching to 'abxde'.
|
||||
act(() => {
|
||||
setShowX(true);
|
||||
});
|
||||
expect(container.textContent).toMatch('abxde');
|
||||
expect(print(store)).toBe(snapshotForABXDE);
|
||||
|
||||
// Verify switching back to 'abcde'.
|
||||
act(() => {
|
||||
setShowX(false);
|
||||
});
|
||||
expect(container.textContent).toMatch('abcde');
|
||||
expect(print(store)).toBe(snapshotForABCDE);
|
||||
|
||||
// Clean up.
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
}
|
||||
|
||||
// 6. Verify *updates* by reusing the container between iterations.
|
||||
// There'll be no unmounting until the very end.
|
||||
container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
root = ReactDOM.unstable_createRoot(container);
|
||||
for (let i = 0; i < cases.length; i++) {
|
||||
// Verify mounting 'abcde'.
|
||||
act(() => root.render(<Parent>{cases[i]}</Parent>));
|
||||
expect(container.textContent).toMatch('abcde');
|
||||
expect(print(store)).toEqual(snapshotForABCDE);
|
||||
|
||||
// Verify switching to 'abxde'.
|
||||
act(() => {
|
||||
setShowX(true);
|
||||
});
|
||||
expect(container.textContent).toMatch('abxde');
|
||||
expect(print(store)).toBe(snapshotForABXDE);
|
||||
|
||||
// Verify switching back to 'abcde'.
|
||||
act(() => {
|
||||
setShowX(false);
|
||||
});
|
||||
expect(container.textContent).toMatch('abcde');
|
||||
expect(print(store)).toBe(snapshotForABCDE);
|
||||
// Don't unmount. Reuse the container between iterations.
|
||||
}
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
});
|
||||
|
||||
it('should handle stress test with reordering (Concurrent Mode)', () => {
|
||||
const A = () => 'a';
|
||||
const B = () => 'b';
|
||||
const C = () => 'c';
|
||||
const D = () => 'd';
|
||||
const E = () => 'e';
|
||||
const a = <A key="a" />;
|
||||
const b = <B key="b" />;
|
||||
const c = <C key="c" />;
|
||||
const d = <D key="d" />;
|
||||
const e = <E key="e" />;
|
||||
|
||||
// prettier-ignore
|
||||
let steps = [
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
e,
|
||||
[a],
|
||||
[b],
|
||||
[c],
|
||||
[d],
|
||||
[e],
|
||||
[a, b],
|
||||
[b, a],
|
||||
[b, c],
|
||||
[c, b],
|
||||
[a, c],
|
||||
[c, a],
|
||||
];
|
||||
|
||||
const Root = ({ children }) => {
|
||||
return children;
|
||||
};
|
||||
|
||||
// 1. Capture the expected render result.
|
||||
let snapshots = [];
|
||||
let container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
let root = ReactDOM.unstable_createRoot(container);
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
act(() => root.render(<Root>{steps[i]}</Root>));
|
||||
// We snapshot each step once so it doesn't regress.
|
||||
expect(store).toMatchSnapshot();
|
||||
snapshots.push(print(store));
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
}
|
||||
|
||||
// 2. Verify that we can update from every step to every other step and back.
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
for (let j = 0; j < steps.length; j++) {
|
||||
let container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
let root = ReactDOM.unstable_createRoot(container);
|
||||
act(() => root.render(<Root>{steps[i]}</Root>));
|
||||
expect(print(store)).toMatch(snapshots[i]);
|
||||
act(() => root.render(<Root>{steps[j]}</Root>));
|
||||
expect(print(store)).toMatch(snapshots[j]);
|
||||
act(() => root.render(<Root>{steps[i]}</Root>));
|
||||
expect(print(store)).toMatch(snapshots[i]);
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Same test as above, but this time we wrap children in a host component.
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
for (let j = 0; j < steps.length; j++) {
|
||||
let container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
let root = ReactDOM.unstable_createRoot(container);
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<div>{steps[i]}</div>
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toMatch(snapshots[i]);
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<div>{steps[j]}</div>
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toMatch(snapshots[j]);
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<div>{steps[i]}</div>
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toMatch(snapshots[i]);
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('should handle a stress test for Suspense (Concurrent Mode)', async () => {
|
||||
const A = () => 'a';
|
||||
const B = () => 'b';
|
||||
const C = () => 'c';
|
||||
const X = () => 'x';
|
||||
const Y = () => 'y';
|
||||
const Z = () => 'z';
|
||||
const a = <A key="a" />;
|
||||
const b = <B key="b" />;
|
||||
const c = <C key="c" />;
|
||||
const z = <Z key="z" />;
|
||||
|
||||
// prettier-ignore
|
||||
const steps = [
|
||||
a,
|
||||
[a],
|
||||
[a, b, c],
|
||||
[c, b, a],
|
||||
[c, null, a],
|
||||
<React.Fragment>{c}{a}</React.Fragment>,
|
||||
<div>{c}{a}</div>,
|
||||
<div><span>{a}</span>{b}</div>,
|
||||
[[a]],
|
||||
null,
|
||||
b,
|
||||
a
|
||||
];
|
||||
|
||||
const Never = () => {
|
||||
throw new Promise(() => {});
|
||||
};
|
||||
|
||||
const Root = ({ children }) => {
|
||||
return children;
|
||||
};
|
||||
|
||||
// 1. For each step, check Suspense can render them as initial primary content.
|
||||
// This is the only step where we use Jest snapshots.
|
||||
let snapshots = [];
|
||||
let container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
let root = ReactDOM.unstable_createRoot(container);
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={z}>{steps[i]}</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
// We snapshot each step once so it doesn't regress.
|
||||
expect(store).toMatchSnapshot();
|
||||
snapshots.push(print(store));
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
}
|
||||
|
||||
// 2. Verify check Suspense can render same steps as initial fallback content.
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={steps[i]}>
|
||||
<Z />
|
||||
<Never />
|
||||
<Z />
|
||||
</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toEqual(snapshots[i]);
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
}
|
||||
|
||||
// 3. Verify we can update from each step to each step in primary mode.
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
for (let j = 0; j < steps.length; j++) {
|
||||
// Always start with a fresh container and steps[i].
|
||||
container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
root = ReactDOM.unstable_createRoot(container);
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={z}>{steps[i]}</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toEqual(snapshots[i]);
|
||||
// Re-render with steps[j].
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={z}>{steps[j]}</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
// Verify the successful transition to steps[j].
|
||||
expect(print(store)).toEqual(snapshots[j]);
|
||||
// Check that we can transition back again.
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={z}>{steps[i]}</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toEqual(snapshots[i]);
|
||||
// Clean up after every iteration.
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Verify we can update from each step to each step in fallback mode.
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
for (let j = 0; j < steps.length; j++) {
|
||||
// Always start with a fresh container and steps[i].
|
||||
container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
root = ReactDOM.unstable_createRoot(container);
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={steps[i]}>
|
||||
<Z />
|
||||
<Never />
|
||||
<Z />
|
||||
</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toEqual(snapshots[i]);
|
||||
// Re-render with steps[j].
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={steps[j]}>
|
||||
<Z />
|
||||
<Never />
|
||||
<Z />
|
||||
</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
// Verify the successful transition to steps[j].
|
||||
expect(print(store)).toEqual(snapshots[j]);
|
||||
// Check that we can transition back again.
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={steps[i]}>
|
||||
<Z />
|
||||
<Never />
|
||||
<Z />
|
||||
</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toEqual(snapshots[i]);
|
||||
// Clean up after every iteration.
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Verify we can update from each step to each step when moving primary -> fallback.
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
for (let j = 0; j < steps.length; j++) {
|
||||
// Always start with a fresh container and steps[i].
|
||||
container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
root = ReactDOM.unstable_createRoot(container);
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={z}>{steps[i]}</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toEqual(snapshots[i]);
|
||||
// Re-render with steps[j].
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={steps[j]}>
|
||||
<Z />
|
||||
<Never />
|
||||
<Z />
|
||||
</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
// Verify the successful transition to steps[j].
|
||||
expect(print(store)).toEqual(snapshots[j]);
|
||||
// Check that we can transition back again.
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={z}>{steps[i]}</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toEqual(snapshots[i]);
|
||||
// Clean up after every iteration.
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Verify we can update from each step to each step when moving fallback -> primary.
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
for (let j = 0; j < steps.length; j++) {
|
||||
// Always start with a fresh container and steps[i].
|
||||
container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
root = ReactDOM.unstable_createRoot(container);
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={steps[i]}>
|
||||
<Z />
|
||||
<Never />
|
||||
<Z />
|
||||
</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toEqual(snapshots[i]);
|
||||
// Re-render with steps[j].
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={z}>{steps[j]}</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
// Verify the successful transition to steps[j].
|
||||
expect(print(store)).toEqual(snapshots[j]);
|
||||
// Check that we can transition back again.
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={steps[i]}>
|
||||
<Z />
|
||||
<Never />
|
||||
<Z />
|
||||
</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toEqual(snapshots[i]);
|
||||
// Clean up after every iteration.
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Verify we can update from each step to each step when toggling Suspense.
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
for (let j = 0; j < steps.length; j++) {
|
||||
// Always start with a fresh container and steps[i].
|
||||
container = document.createElement('div');
|
||||
// $FlowFixMe
|
||||
root = ReactDOM.unstable_createRoot(container);
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={steps[j]}>{steps[i]}</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
|
||||
// We get ID from the index in the tree above:
|
||||
// Root, X, Suspense, ...
|
||||
// ^ (index is 2)
|
||||
const suspenseID = store.getElementIDAtIndex(2);
|
||||
|
||||
// Force fallback.
|
||||
expect(print(store)).toEqual(snapshots[i]);
|
||||
act(() => {
|
||||
const suspenseID = store.getElementIDAtIndex(2);
|
||||
bridge.send('overrideSuspense', {
|
||||
id: suspenseID,
|
||||
rendererID: store.getRendererIDForElement(suspenseID),
|
||||
forceFallback: true,
|
||||
});
|
||||
});
|
||||
expect(print(store)).toEqual(snapshots[j]);
|
||||
|
||||
// Stop forcing fallback.
|
||||
act(() => {
|
||||
bridge.send('overrideSuspense', {
|
||||
id: suspenseID,
|
||||
rendererID: store.getRendererIDForElement(suspenseID),
|
||||
forceFallback: false,
|
||||
});
|
||||
});
|
||||
expect(print(store)).toEqual(snapshots[i]);
|
||||
|
||||
// Trigger actual fallback.
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={steps[j]}>
|
||||
<Z />
|
||||
<Never />
|
||||
<Z />
|
||||
</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
expect(print(store)).toEqual(snapshots[j]);
|
||||
|
||||
// Force fallback while we're in fallback mode.
|
||||
act(() => {
|
||||
bridge.send('overrideSuspense', {
|
||||
id: suspenseID,
|
||||
rendererID: store.getRendererIDForElement(suspenseID),
|
||||
forceFallback: true,
|
||||
});
|
||||
});
|
||||
// Keep seeing fallback content.
|
||||
expect(print(store)).toEqual(snapshots[j]);
|
||||
|
||||
// Switch to primary mode.
|
||||
act(() =>
|
||||
root.render(
|
||||
<Root>
|
||||
<X />
|
||||
<React.Suspense fallback={steps[j]}>{steps[i]}</React.Suspense>
|
||||
<Y />
|
||||
</Root>
|
||||
)
|
||||
);
|
||||
// Fallback is still forced though.
|
||||
expect(print(store)).toEqual(snapshots[j]);
|
||||
|
||||
// Stop forcing fallback. This reverts to primary content.
|
||||
act(() => {
|
||||
bridge.send('overrideSuspense', {
|
||||
id: suspenseID,
|
||||
rendererID: store.getRendererIDForElement(suspenseID),
|
||||
forceFallback: false,
|
||||
});
|
||||
});
|
||||
// Now we see primary content.
|
||||
expect(print(store)).toEqual(snapshots[i]);
|
||||
|
||||
// Clean up after every iteration.
|
||||
act(() => root.unmount());
|
||||
expect(print(store)).toBe('');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
+14
-15
@@ -22,7 +22,6 @@ import {
|
||||
TREE_OPERATION_ADD,
|
||||
TREE_OPERATION_REMOVE,
|
||||
TREE_OPERATION_RESET_CHILDREN,
|
||||
TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN,
|
||||
TREE_OPERATION_UPDATE_TREE_BASE_DURATION,
|
||||
} from '../constants';
|
||||
import { getUID } from '../utils';
|
||||
@@ -772,15 +771,6 @@ export function attach(
|
||||
}
|
||||
}
|
||||
|
||||
function recordRecursiveRemoveChildren(fiber) {
|
||||
const primaryFiber = getPrimaryFiber(fiber);
|
||||
const id = getFiberID(primaryFiber);
|
||||
beginNextOperation(2);
|
||||
nextOperation[0] = TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN;
|
||||
nextOperation[1] = id;
|
||||
endNextOperation(false);
|
||||
}
|
||||
|
||||
function mountFiberRecursively(
|
||||
fiber: Fiber,
|
||||
parentFiber: Fiber | null,
|
||||
@@ -828,6 +818,18 @@ export function attach(
|
||||
}
|
||||
}
|
||||
|
||||
function unmountFiberChildrenRecursively(fiber: Fiber) {
|
||||
if (__DEBUG__) {
|
||||
debug('unmountFiberChildrenRecursively()', fiber);
|
||||
}
|
||||
let child = fiber.child;
|
||||
while (child !== null) {
|
||||
recordUnmount(child);
|
||||
unmountFiberChildrenRecursively(child);
|
||||
child = child.sibling;
|
||||
}
|
||||
}
|
||||
|
||||
function recordTreeDuration(fiber: Fiber) {
|
||||
const id = getFiberID(getPrimaryFiber(fiber));
|
||||
const { actualDuration, treeBaseDuration } = fiber;
|
||||
@@ -955,11 +957,8 @@ export function attach(
|
||||
// Primary -> Fallback:
|
||||
// 1. Hide primary set
|
||||
// This is not a real unmount, so it won't get reported by React.
|
||||
// By this point it's *too late* to find the previous primary child set
|
||||
// so we'll just tell the store to "forget" about those children.
|
||||
// They might "resurface" later when we switch to primary content,
|
||||
// but from the store's point of view they will be a new tree.
|
||||
recordRecursiveRemoveChildren(nextFiber);
|
||||
// We need to manually walk the previous tree and record unmounts.
|
||||
unmountFiberChildrenRecursively(prevFiber);
|
||||
// 2. Mount fallback set
|
||||
const nextFallbackChildSet = nextFiber.child.sibling;
|
||||
mountFiberRecursively(nextFallbackChildSet, nextFiber, true);
|
||||
|
||||
@@ -4,7 +4,6 @@ export const TREE_OPERATION_ADD = 1;
|
||||
export const TREE_OPERATION_REMOVE = 2;
|
||||
export const TREE_OPERATION_RESET_CHILDREN = 3;
|
||||
export const TREE_OPERATION_UPDATE_TREE_BASE_DURATION = 4;
|
||||
export const TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN = 5;
|
||||
|
||||
export const LOCAL_STORAGE_RELOAD_AND_PROFILE_KEY =
|
||||
'React::DevTools::reloadAndProfile';
|
||||
|
||||
@@ -5,7 +5,6 @@ import memoize from 'memoize-one';
|
||||
import throttle from 'lodash.throttle';
|
||||
import {
|
||||
TREE_OPERATION_ADD,
|
||||
TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN,
|
||||
TREE_OPERATION_REMOVE,
|
||||
TREE_OPERATION_RESET_CHILDREN,
|
||||
TREE_OPERATION_UPDATE_TREE_BASE_DURATION,
|
||||
@@ -695,51 +694,6 @@ export default class Store extends EventEmitter {
|
||||
weightDelta = 1;
|
||||
}
|
||||
break;
|
||||
case TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN: {
|
||||
id = ((operations[i + 1]: any): number);
|
||||
|
||||
if (!this._idToElement.has(id)) {
|
||||
throw new Error(
|
||||
'Store does not contain fiber ' +
|
||||
id +
|
||||
'. This is a bug in React DevTools.'
|
||||
);
|
||||
}
|
||||
|
||||
i = i + 2;
|
||||
|
||||
let justRemovedIDs = [];
|
||||
const recursivelyRemove = childID => {
|
||||
justRemovedIDs.push(childID);
|
||||
const child = this._idToElement.get(childID);
|
||||
if (!child) {
|
||||
throw new Error(
|
||||
'Store does not contain fiber ' +
|
||||
childID +
|
||||
'. This is a bug in React DevTools.'
|
||||
);
|
||||
}
|
||||
this._idToElement.delete(childID);
|
||||
child.children.forEach(recursivelyRemove);
|
||||
};
|
||||
|
||||
// Track removed items so search results can be updated
|
||||
const oldRemovedElementIDs = removedElementIDs;
|
||||
removedElementIDs = new Uint32Array(
|
||||
removedElementIDs.length + justRemovedIDs.length
|
||||
);
|
||||
removedElementIDs.set(oldRemovedElementIDs);
|
||||
let startIndex = oldRemovedElementIDs.length;
|
||||
for (let j = 0; j < justRemovedIDs.length; j++) {
|
||||
removedElementIDs[startIndex + j] = oldRemovedElementIDs[j];
|
||||
}
|
||||
|
||||
parentElement = ((this._idToElement.get(id): any): Element);
|
||||
parentElement.children.forEach(recursivelyRemove);
|
||||
parentElement.children = [];
|
||||
weightDelta = -parentElement.weight + 1;
|
||||
break;
|
||||
}
|
||||
case TREE_OPERATION_REMOVE: {
|
||||
id = ((operations[i + 1]: any): number);
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import {
|
||||
__DEBUG__,
|
||||
TREE_OPERATION_ADD,
|
||||
TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN,
|
||||
TREE_OPERATION_REMOVE,
|
||||
TREE_OPERATION_RESET_CHILDREN,
|
||||
TREE_OPERATION_UPDATE_TREE_BASE_DURATION,
|
||||
@@ -256,37 +255,6 @@ function updateTree(
|
||||
nodes.set(id, node);
|
||||
}
|
||||
break;
|
||||
case TREE_OPERATION_RECURSIVE_REMOVE_CHILDREN:
|
||||
id = ((operations[i + 1]: any): number);
|
||||
|
||||
i = i + 2;
|
||||
|
||||
if (!nodes.has(id)) {
|
||||
throw new Error(
|
||||
'Commit tree does not contain fiber ' +
|
||||
id +
|
||||
'. This is a bug in React DevTools.'
|
||||
);
|
||||
}
|
||||
|
||||
node = getClonedNode(id);
|
||||
|
||||
const recursivelyRemove = childID => {
|
||||
if (!nodes.has(id)) {
|
||||
throw new Error(
|
||||
'Commit tree does not contain fiber ' +
|
||||
id +
|
||||
'. This is a bug in React DevTools.'
|
||||
);
|
||||
}
|
||||
const child = getClonedNode(childID);
|
||||
nodes.delete(childID);
|
||||
child.children.forEach(recursivelyRemove);
|
||||
};
|
||||
|
||||
node.children.forEach(recursivelyRemove);
|
||||
node.children = [];
|
||||
break;
|
||||
case TREE_OPERATION_REMOVE:
|
||||
id = ((operations[i + 1]: any): number);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user