Files
effect-view/packages/vite-plugin/test/runtime.test.ts
T
Julien Valverdé c40df980ed
Lint / lint (push) Failing after 38s
Rename vite plugin
2026-07-25 22:44:09 +02:00

73 lines
2.7 KiB
TypeScript

import type * as Component from "effect-fc-next/Component"
import * as Refreshable from "effect-fc-next/Refreshable"
import { describe, expect, it, vi } from "vitest"
import { accept, register } from "../src/runtime.js"
describe("refresh runtime", () => {
const component = <A extends object>(value: A): A & Component.Component.Any =>
value as A & Component.Component.Any
it("retains a cell and notifies subscribers for compatible updates", async () => {
const hot = {
data: {},
accept: vi.fn(),
invalidate: vi.fn(),
}
const first = register(component({ body: "first" }), hot, "module:View", "hooks")
const cell = (first as Record<PropertyKey, unknown>)[Refreshable.RefreshableTypeId] as Refreshable.Cell
const listener = vi.fn()
cell.subscribe(listener)
const second = register(component({ body: "second" }), hot, "module:View", "hooks")
const secondCell = (second as Record<PropertyKey, unknown>)[Refreshable.RefreshableTypeId]
expect(secondCell).toBe(cell)
expect(cell.current).toBe(second)
expect(cell.snapshot).toEqual({
revision: 1,
resetRevision: 0,
})
await Promise.resolve()
expect(listener).toHaveBeenCalledTimes(1)
})
it("increments resetRevision for incompatible and forced updates", () => {
const hot = {
data: {},
accept: vi.fn(),
invalidate: vi.fn(),
}
const first = register(component({}), hot, "module:View", "one")
const cell = (first as Record<PropertyKey, unknown>)[Refreshable.RefreshableTypeId] as Refreshable.Cell
register(component({}), hot, "module:View", "two")
expect(cell.snapshot.resetRevision).toBe(1)
register(component({}), hot, "module:View", "two", true)
expect(cell.snapshot.resetRevision).toBe(2)
})
it("is inert outside a Vite hot context", () => {
const descriptor = component({})
expect(register(descriptor, undefined, "module:View", "hooks")).toBe(descriptor)
expect((descriptor as Record<PropertyKey, unknown>)[Refreshable.RefreshableTypeId]).toBeUndefined()
})
it("invalidates when the module's View IDs change", () => {
const hot = {
data: {},
accept: vi.fn(),
invalidate: vi.fn(),
}
accept(hot, ["module:First"])
expect(hot.accept).toHaveBeenCalledTimes(1)
expect(hot.invalidate).not.toHaveBeenCalled()
accept(hot, ["module:Second"])
expect(hot.invalidate).toHaveBeenCalledWith("[effect-view] Effect View exports changed")
})
})