import type { Cache } from "@rotorsoft/act/types"; /** * One {@link Cache} implementation to feed into * {@link runCacheDifferentialTck}. The harness drives the identical * generated workload against all of them, then compares the observable * `get()` snapshot after every operation. */ export type DifferentialCache = { /** Display name used in assertion messages and the describe block. */ readonly name: string; /** * Produces the cache under test. Called once in `beforeAll`; the * harness owns its lifecycle (`dispose`). Must return an empty cache * with capacity for at least {@link CacheDifferentialTckOptions.streams} * entries so nothing is evicted mid-comparison. */ readonly factory: () => Cache | Promise; }; /** * Options for {@link runCacheDifferentialTck}. */ export type CacheDifferentialTckOptions = { /** Display name for the differential suite. */ readonly name: string; /** * Two or more caches to drive in lockstep and compare. The first entry * is the reference; every other cache's observable `get()` snapshot * must match it exactly after every operation. */ readonly caches: ReadonlyArray; /** * Base PRNG seed. Workload `r` of {@link CacheDifferentialTckOptions.runs} * is built from `seed + r`, so the campaign is reproducible. Default * `0xcac`. */ readonly seed?: number; /** * Number of distinct streams (cache keys) per workload. Kept small so a * bounded cache never evicts during the comparison. Default `6`. */ readonly streams?: number; /** * How many independent randomized workloads to generate and compare, * each from a distinct seed. Default `8`. */ readonly runs?: number; }; /** * Cross-implementation differential contract for the {@link Cache} port * (#1057). * * Where {@link runCacheTck} pins each method's contract against a single * implementation, this harness drives a **family of randomized, seeded * workloads** (`set` / `invalidate` / `clear`) against two or more caches * in lockstep and asserts their observable `get()` snapshot is identical * after **every** operation. A cache that mishandles overwrite ordering, * leaks an invalidated key, or clears partially diverges from the * reference on the exact operation that broke it — with the seed in the * describe block for replay. * * Streams stay within the cache's capacity, so eviction (an adapter * policy, not a contract guarantee) never enters the comparison. * * @example * ```ts * import { runCacheDifferentialTck } from "@rotorsoft/act-tck"; * import { InMemoryCache } from "@rotorsoft/act"; * import { RedisCache } from "../src/index.js"; * * runCacheDifferentialTck({ * name: "InMemory vs Redis", * caches: [ * { name: "InMemoryCache", factory: () => new InMemoryCache({ maxSize: 1000 }) }, * { name: "RedisCache", factory: () => new RedisCache({ url: process.env.REDIS_URL }) }, * ], * }); * ``` */ export declare const runCacheDifferentialTck: (options: CacheDifferentialTckOptions) => void; //# sourceMappingURL=cache-differential-tck.d.ts.map