mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-30 22:03:58 +00:00
129 lines
4.3 KiB
TypeScript
129 lines
4.3 KiB
TypeScript
import { afterEach, describe, expect, test } from "bun:test"
|
|
import { Effect } from "effect"
|
|
import { runtime, runPromiseInstance } from "../../src/effect/runtime"
|
|
import { Auth } from "../../src/auth/effect"
|
|
import { Instances } from "../../src/effect/instances"
|
|
import { Instance } from "../../src/project/instance"
|
|
import { ProviderAuth } from "../../src/provider/auth"
|
|
import { Vcs } from "../../src/project/vcs"
|
|
import { Question } from "../../src/question"
|
|
import { tmpdir } from "../fixture/fixture"
|
|
|
|
/**
|
|
* Integration tests for the Effect runtime and LayerMap-based instance system.
|
|
*
|
|
* Each instance service layer has `.pipe(Layer.fresh)` at its definition site
|
|
* so it is always rebuilt per directory, while shared dependencies are provided
|
|
* outside the fresh boundary and remain memoizable.
|
|
*
|
|
* These tests verify the invariants using object identity (===) on the real
|
|
* production services — not mock services or return-value checks.
|
|
*/
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
const grabInstance = (service: any) => runPromiseInstance(service.use(Effect.succeed))
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
const grabGlobal = (service: any) => runtime.runPromise(service.use(Effect.succeed))
|
|
|
|
describe("effect/runtime", () => {
|
|
afterEach(async () => {
|
|
await Instance.disposeAll()
|
|
})
|
|
|
|
test("global services are shared across directories", async () => {
|
|
await using one = await tmpdir({ git: true })
|
|
await using two = await tmpdir({ git: true })
|
|
|
|
// Auth is a global service — it should be the exact same object
|
|
// regardless of which directory we're in.
|
|
const authOne = await Instance.provide({
|
|
directory: one.path,
|
|
fn: () => grabGlobal(Auth.Service),
|
|
})
|
|
|
|
const authTwo = await Instance.provide({
|
|
directory: two.path,
|
|
fn: () => grabGlobal(Auth.Service),
|
|
})
|
|
|
|
expect(authOne).toBe(authTwo)
|
|
})
|
|
|
|
test("instance services with global deps share the global (ProviderAuth → Auth)", async () => {
|
|
await using one = await tmpdir({ git: true })
|
|
await using two = await tmpdir({ git: true })
|
|
|
|
// ProviderAuth depends on Auth via defaultLayer.
|
|
// The instance service itself should be different per directory,
|
|
// but the underlying Auth should be shared.
|
|
const paOne = await Instance.provide({
|
|
directory: one.path,
|
|
fn: () => grabInstance(ProviderAuth.Service),
|
|
})
|
|
|
|
const paTwo = await Instance.provide({
|
|
directory: two.path,
|
|
fn: () => grabInstance(ProviderAuth.Service),
|
|
})
|
|
|
|
// Different directories → different ProviderAuth instances.
|
|
expect(paOne).not.toBe(paTwo)
|
|
|
|
// But the global Auth is the same object in both.
|
|
const authOne = await Instance.provide({
|
|
directory: one.path,
|
|
fn: () => grabGlobal(Auth.Service),
|
|
})
|
|
const authTwo = await Instance.provide({
|
|
directory: two.path,
|
|
fn: () => grabGlobal(Auth.Service),
|
|
})
|
|
expect(authOne).toBe(authTwo)
|
|
})
|
|
|
|
test("instance services are shared within the same directory", async () => {
|
|
await using tmp = await tmpdir({ git: true })
|
|
|
|
await Instance.provide({
|
|
directory: tmp.path,
|
|
fn: async () => {
|
|
expect(await grabInstance(Vcs.Service)).toBe(await grabInstance(Vcs.Service))
|
|
expect(await grabInstance(Question.Service)).toBe(await grabInstance(Question.Service))
|
|
},
|
|
})
|
|
})
|
|
|
|
test("different directories get different service instances", async () => {
|
|
await using one = await tmpdir({ git: true })
|
|
await using two = await tmpdir({ git: true })
|
|
|
|
const vcsOne = await Instance.provide({
|
|
directory: one.path,
|
|
fn: () => grabInstance(Vcs.Service),
|
|
})
|
|
|
|
const vcsTwo = await Instance.provide({
|
|
directory: two.path,
|
|
fn: () => grabInstance(Vcs.Service),
|
|
})
|
|
|
|
expect(vcsOne).not.toBe(vcsTwo)
|
|
})
|
|
|
|
test("disposal rebuilds services with a new instance", async () => {
|
|
await using tmp = await tmpdir({ git: true })
|
|
|
|
await Instance.provide({
|
|
directory: tmp.path,
|
|
fn: async () => {
|
|
const before = await grabInstance(Question.Service)
|
|
|
|
await runtime.runPromise(Instances.use((map) => map.invalidate(Instance.directory)))
|
|
|
|
const after = await grabInstance(Question.Service)
|
|
expect(after).not.toBe(before)
|
|
},
|
|
})
|
|
})
|
|
})
|