-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathstrictAndConcurrentModeUsingFinalizationRegistry.test.tsx
More file actions
60 lines (52 loc) · 2.11 KB
/
Copy pathstrictAndConcurrentModeUsingFinalizationRegistry.test.tsx
File metadata and controls
60 lines (52 loc) · 2.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import { cleanup, render, waitFor } from "@testing-library/react"
import * as mobx from "mobx"
import * as React from "react"
import { useObserver } from "../src/useObserver"
import gc from "expose-gc/function"
import { observerFinalizationRegistry } from "../src/utils/observerFinalizationRegistry"
if (typeof globalThis.FinalizationRegistry !== "function") {
throw new Error("This test must run with node >= 14")
}
expect(observerFinalizationRegistry).toBeInstanceOf(globalThis.FinalizationRegistry)
afterEach(cleanup)
test("uncommitted components should not leak observations", async () => {
jest.setTimeout(30_000)
const store = mobx.observable({ count1: 0, count2: 0 })
// Track whether counts are observed
let count1IsObserved = false
let count2IsObserved = false
mobx.onBecomeObserved(store, "count1", () => (count1IsObserved = true))
mobx.onBecomeUnobserved(store, "count1", () => (count1IsObserved = false))
mobx.onBecomeObserved(store, "count2", () => (count2IsObserved = true))
mobx.onBecomeUnobserved(store, "count2", () => (count2IsObserved = false))
const TestComponent1 = () => useObserver(() => <div>{store.count1}</div>)
const TestComponent2 = () => useObserver(() => <div>{store.count2}</div>)
// Render, then remove only #2
const rendering = render(
<React.StrictMode>
<TestComponent1 />
<TestComponent2 />
</React.StrictMode>
)
rendering.rerender(
<React.StrictMode>
<TestComponent1 />
</React.StrictMode>
)
// Allow gc to kick in in case to let finalization registry cleanup
await new Promise(resolve => setTimeout(resolve, 100))
gc()
// Can take a while (especially on CI) before gc actually calls the registry
await waitFor(
() => {
// count1 should still be being observed by Component1,
// but count2 should have had its reaction cleaned up.
expect(count1IsObserved).toBeTruthy()
expect(count2IsObserved).toBeFalsy()
},
{
timeout: 15_000,
interval: 200
}
)
})