import type { Duration } from "effect"; import { Effect, Layer } from "effect"; import { TestClock } from "effect/testing"; import type { EffectRunner } from "../boundary/index.js"; /** * Fork `effect`, advance the `TestClock` by `duration`, then join it: the * fork/adjust/join dance every test of a sleeping, retrying or scheduled effect * needs, because an effect that sleeps on the test clock blocks until the clock * moves and the clock cannot move from the fiber that is blocked. * * Use this inside `it.effect`, where `@effect/vitest` already provides the test * clock. A bare number of milliseconds is a valid `duration`, as is * `"10 seconds"`. */ export declare const withVirtualTime: (effect: Effect.Effect, duration: Duration.Input) => Effect.Effect; /** * The Promise form of `withVirtualTime` for a plain (non-`it.effect`) test: it * supplies its own `TestClock` layer, so a ten second sleep costs no wall time. * * ```ts * const value = await runWithVirtualTime(retryingFetch, "1 minute"); * ``` * * Prefer `withVirtualTime` under `@effect/vitest`'s `it.effect`; this exists * for tests that are not written as effects. */ export declare function runWithVirtualTime(effect: Effect.Effect, duration: Duration.Input): Promise; /** What `trackedTmpDirs` hands back: a factory for swept scratch directories. */ export interface TrackedTmpDirs { /** Create a fresh directory under the OS temp dir, removed after the suite. */ readonly tmp: (prefix: string) => string; } /** * Register a tracked temp-directory factory plus one `afterAll` sweep for the * current test file. Call it once at file or `describe` scope (never inside a * test, where vitest refuses to register hooks); each `tmp(prefix)` call * `mkdtemp`s a fresh directory and queues it for removal once the suite ends. * * ```ts * const { tmp } = trackedTmpDirs(); * it("writes a file", () => { const dir = tmp("my-suite-"); ... }); * ``` * * Synchronous on purpose: it is called from vitest's collection phase, not from * an effect. Use `tmpDir` when the directory should die with a `Scope` instead. */ export declare function trackedTmpDirs(): TrackedTmpDirs; /** * A scratch directory that lives exactly as long as the enclosing `Scope`: it * is created on acquire and removed recursively on release, including when the * test fiber is interrupted. The scoped counterpart of `trackedTmpDirs`, and * the one to use inside `it.effect`, which already provides a `Scope`. * * Fails with `OperationError` if the directory cannot be created. */ export declare const tmpDir: (prefix: string) => Effect.Effect; /** * Build `layer` once and expose it as an `EffectRunner`, so a production entry * point that takes a runner (see `makeBoundary` in * `@micthiesen/mitools/boundary`) can be driven under test layers such as * `TestClock`. The layer's resources are released when the enclosing `Scope` * closes, which under `it.effect` is the end of the test. * * ```ts * it.effect("retries through the boundary", () => * Effect.gen(function* () { * const runner = yield* testRuntime(Layer.mergeAll(TestClock.layer(), Api.layerStub)); * const { runQuery } = makeBoundary(runner); * startTheApp({ runQuery }); * yield* TestClock.adjust("1 minute"); * }), * ); * ``` * * The returned runner has no layer error of its own: a failing layer fails this * effect instead, at the point the runner is built. */ export declare const testRuntime: (layer: Layer.Layer) => Effect.Effect, E, import("effect/Scope").Scope>;