improve finalizationRegistry test util

This commit is contained in:
Víctor Oliva 2022-10-27 14:02:00 +01:00
parent ed4c2a49c4
commit 8aefadfd72
3 changed files with 42 additions and 48 deletions

View File

@ -1,39 +0,0 @@
import "expose-gc"
export function testFinalizationRegistry() {
const promises = new Map<
string,
Promise<string> & { resolve: (tag: string) => void }
>()
const finalizationRegistry = new FinalizationRegistry((tag: any) => {
if (!promises.has(tag)) {
const promise = Object.assign(Promise.resolve(tag), { resolve: () => {} })
promises.set(tag, promise)
} else {
promises.get(tag)!.resolve(tag)
}
})
function tag<T extends object>(tag: string, v: T) {
if (!promises.has(tag)) {
let resolve = (_tag: string) => {}
const promise = new Promise<string>((res) => {
resolve = res
})
Object.assign(promise, { resolve })
promises.set(tag, promise as any)
finalizationRegistry.register(v, tag)
}
return v
}
return {
tag,
getPromise(tag: string) {
return promises.get(tag)!
},
gc() {
global.gc!()
},
}
}

View File

@ -14,7 +14,7 @@ import {
} from "rxjs"
import { createRoot } from "./create-root"
import { createSignal } from "./create-signal"
import { testFinalizationRegistry } from "./finalizationRegistry"
import { testFinalizationRegistry } from "./test-utils/finalizationRegistry"
import { routeState } from "./route-state"
import { substate } from "./substate"
@ -515,15 +515,12 @@ describe("subState", () => {
const nodeA = substate(root, () =>
fr.tag("nodeA", concat(from([1, 2, 3]), NEVER)),
)
fr.gc()
const stop = root.run()
expect(nodeA.getValue()).toEqual(3)
stop()
fr.gc()
await expect(fr.getPromise("nodeA")).resolves.toEqual("nodeA")
await fr.assertFinalized("nodeA")
})
it("doesn't hold references to dead instances, even on circular references", async () => {
@ -550,7 +547,6 @@ describe("subState", () => {
getState$(nodeA).pipe(map((v) => v + "$b$")),
),
)
fr.gc()
root.run("b")
const stopA = root.run("a")
@ -560,10 +556,9 @@ describe("subState", () => {
signal.push({ gameId: "a" }, null)
expect(nodeA.getValue({ gameId: "a" })).toEqual("/a/$b$/a/$b$/a/")
stopA()
fr.gc()
await expect(fr.getPromise("nodeA-a")).resolves.toBe("nodeA-a")
await expect(fr.getPromise("nodeB-a")).resolves.toBe("nodeB-a")
await fr.assertFinalized("nodeA-a")
await fr.assertFinalized("nodeB-a")
})
})
})

View File

@ -0,0 +1,38 @@
import "expose-gc"
export function testFinalizationRegistry() {
const promises = new Map<
string,
Promise<string> & { resolve: (tag: string) => void }
>()
const finalizationRegistry = new FinalizationRegistry((tag: any) => {
promises.get(tag)!.resolve(tag)
})
function tag<T extends object>(tag: string, v: T) {
if (promises.has(tag)) {
throw new Error("TestFinalizationRegistry: tags must be unique")
}
let resolve = (_tag: string) => {}
const promise = new Promise<string>((res) => {
resolve = res
})
Object.assign(promise, { resolve })
promises.set(tag, promise as any)
finalizationRegistry.register(v, tag)
return v
}
return {
tag,
assertFinalized(tag: string) {
global.gc!()
const promise = promises.get(tag)
expect(promise).not.toBe(undefined)
// I was doing expect(promise).resolves.toEqual(tag), but that's not testing what it should
// `promise` will resolve when the object gets garbage-collected, if it doesn't, the test times out.
// This is equivalent to just awaiting the promise:
return promise
},
}
}