UNPKG

@inngest/test

Version:
229 lines (228 loc) 8.33 kB
import { Context, EventPayload, InngestFunction } from "inngest"; import { InngestTestRun } from "./InngestTestRun.js"; import type { Mock } from "./spy.js"; import { type DeepPartial } from "./util.js"; /** * A test engine for running Inngest functions in a test environment, providing * the ability to assert inputs, outputs, and step usage, as well as mocking * with support for popular testing libraries. */ export declare namespace InngestTestEngine { /** * Options for creating a new {@link InngestTestEngine} instance. */ interface Options { /** * The function to test. * * TODO Potentially later allow many functions such that we can invoke and * send events. */ function: InngestFunction.Like; /** * The event payloads to send to the function. If none is given, an * "inngest/function.invoked" event will be mocked. */ events?: [EventPayload, ...EventPayload[]]; /** * Previous step state to use for this execution. If not provided, none will * be used. It's recommended to use `run.waitFor()`, where this will be * filled automatically as the run progresses. */ steps?: MockedStep[]; /** * The human-readable ID of the step that this execution is attempting to * run. This is mostly an internal detail; it's recommended to use * `run.waitFor()`, where this will be filled automatically as the run * progresses. */ targetStepId?: string; /** * An internal option to disable immediate execution of steps during * parallelism. It's recommended to use `run.waitFor()`, where this will be * filled automatically as the run progresses. */ disableImmediateExecution?: boolean; /** * Request arguments that will be passed to the function execution. * * These can be used by middleware that relies on particular serve handler usage. * If not provided, an empty array will be used. */ reqArgs?: unknown[]; /** * A function that can transform the context sent to the function upon * execution, useful for mocking steps, events, or tracking property * accesses with proxies. * * By default, this will change all `step.*` tools to be mocked functions so * that you can assert their usage, input, and output. If you specify this * option yourself, you'll overwrite this behavior. * * If you wish to keep this behaviour and make additional changes, you can * use the `mockContext` function exported from this module. * * @example Transforming in addition to the defaults * ```ts * import { mockCtx } from "@inngest/test"; * * { * transformCtx: (rawCtx) => { * const ctx = mockCtx(rawCtx); * * // your other changes * * return ctx; * }, * } * ``` */ transformCtx?: (ctx: Context.Any) => Context.Any; } interface MockedStep { id: string; idIsHashed?: boolean; handler: () => any; } type DeepMock<T> = T extends (...args: any[]) => any ? Mock<T> : T extends object ? { [K in keyof T]: DeepMock<T[K]>; } : T; /** * A mocked context object that allows you to assert step usage, input, and * output. */ interface MockContext extends Omit<Context.Any, "step"> { step: DeepMock<Context.Any["step"]>; } /** * Options that can be passed to an existing execution or run to continue * execution. */ type InlineOptions = Omit<Options, "function">; /** * Options that can be passed to an initial execution that then waits for a * particular checkpoint to occur. */ type ExecuteOptions<T extends InngestTestRun.CheckpointKey = InngestTestRun.CheckpointKey> = InlineOptions & { /** * An optional subset of the checkpoint to match against. Any checkpoint of * this type will be matched. * * When providing a `subset`, use `expect` tooling such as * `expect.stringContaining` to match partial values. */ subset?: DeepPartial<InngestTestRun.Checkpoint<T>>; }; type ExecuteStepOptions = InlineOptions & { subset?: DeepPartial<InngestTestRun.Checkpoint<"steps-found">>; }; /** * A mocked state object that allows you to assert step usage, input, and * output. */ type MockState = Record<string, Promise<unknown>>; /** * The output of an individual function execution. */ interface ExecutionOutput<T extends InngestTestRun.CheckpointKey = InngestTestRun.CheckpointKey> { /** * The result of the execution. */ result: InngestTestRun.Checkpoint<T>; /** * The mocked context object that allows you to assert step usage, input, * and output. * * @TODO This type may vary is `transformCtx` is given. */ ctx: InngestTestEngine.MockContext; /** * The mocked state object that allows you to assert step usage, input, and * output. */ state: InngestTestEngine.MockState; /** * An {@link InngestTestRun} instance that allows you to wait for specific * checkpoints in the execution. */ run: InngestTestRun; } } /** * A cache for storing mock handler execution results across multiple executions. * This ensures handlers are only called once per test run. */ interface MockHandlerCache { [stepId: string]: { executed: boolean; promise?: Promise<void>; data?: any; error?: any; lazyHandlers: Array<(state: { data?: any; error?: any; }) => Promise<void>>; }; } /** * A test engine for running Inngest functions in a test environment, providing * the ability to assert inputs, outputs, and step usage, as well as mocking * with support for popular testing libraries. */ export declare class InngestTestEngine { protected options: InngestTestEngine.Options; protected mockHandlerCache: MockHandlerCache; constructor(options: InngestTestEngine.Options); /** * Create a new test engine with the given inline options merged with the * existing options. */ clone(inlineOpts?: InngestTestEngine.InlineOptions): InngestTestEngine; /** * Start a run from the given state and keep executing the function until a * specific checkpoint is reached. * * Is a shortcut for and uses `run.waitFor()`. */ execute<T extends InngestTestRun.CheckpointKey>( /** * Options and state to start the run with. */ inlineOpts?: InngestTestEngine.ExecuteOptions<T>): Promise<InngestTestRun.RunOutput>; /** * Start a run from the given state and keep executing the function until the * given step has run. */ executeStep( /** * The ID of the step to execute. */ stepId: string, /** * Options and state to start the run with. */ inlineOpts?: InngestTestEngine.ExecuteOptions): Promise<InngestTestRun.RunStepOutput>; /** * Start a run from the given state and keep executing the function until a * specific checkpoint is reached. * * Is a shortcut for and uses `run.waitFor()`. * * @TODO This is a duplicate of `execute` and will probably be removed; it's a * very minor convenience method that deals too much with the internals. */ protected executeAndWaitFor<T extends InngestTestRun.CheckpointKey>( /** * The checkpoint to wait for. */ checkpoint: T, /** * Options and state to start the run with. */ inlineOpts?: InngestTestEngine.ExecuteOptions<T>): Promise<InngestTestEngine.ExecutionOutput<T>>; /** * Execute the function with the given inline options. */ protected individualExecution(inlineOpts?: InngestTestEngine.InlineOptions): Promise<InngestTestEngine.ExecutionOutput>; } export {};