# @probitas/probitas > Version: 0.19.0 Probitas - Scenario-based testing and workflow execution framework. This is the main entry point for the Probitas framework. It provides a fluent API for building and executing scenario-based tests with support for: - **Sequential steps**: Define test steps that execute in order with type-safe context passing - **Skip conditions**: Conditionally skip steps or entire scenarios - **Rich assertions**: Built-in expect utilities for comprehensive assertions - **External clients**: Pre-configured clients for HTTP, databases, message queues, and more - **Test utilities**: Faker for test data, time mocking, and function spies ## Links - [GitHub Repository](https://github.com/probitas-test/probitas) - [Documentation](./.claude/README.md) ## Related Packages | Package | Description | |---------|-------------| | [@probitas/builder](https://jsr.io/@probitas/builder) | Fluent API for building scenario definitions | | [@probitas/runner](https://jsr.io/@probitas/runner) | Test execution engine with retry and concurrency | | [@probitas/reporter](https://jsr.io/@probitas/reporter) | Output formatters (list, dot, TAP, JSON) | | [@probitas/core](https://jsr.io/@probitas/core) | Core type definitions and utilities | | [@probitas/discover](https://jsr.io/@probitas/discover) | Scenario file discovery | | [@probitas/logger](https://jsr.io/@probitas/logger) | Unified logging interface | | [@probitas/cli](https://jsr.io/@probitas/cli) | Command-line interface | ## Core Exports - {@linkcode scenario} - Factory function to create scenario builders - {@linkcode Skip} - Utility to skip steps or scenarios conditionally - {@linkcode StepContext} - Type representing the context passed to each step - {@linkcode client} - Namespace containing all available client implementations - {@linkcode expect} - Assertion utilities (from `@std/expect`) ## Re-exported Utilities For convenience, this module also re-exports commonly used testing utilities: - `faker` - Fake data generation from `@faker-js/faker` - `FakeTime` - Time mocking utilities from `@std/testing/time` - `spy`, `stub`, `assertSpyCalls` - Mock utilities from `@std/testing/mock` - `tryOr`, `raise` - Error handling utilities from `@core/errorutil` - `outdent` - Template literal tag for removing indentation ## Classes ### `Skip` ```typescript class Skip extends Error ``` Exception class for conditionally skipping scenario execution. Throw `Skip` from any step, setup, or resource fn to skip the entire scenario. Skipped scenarios are counted separately in the summary and don't count as failures. Common use cases: - Feature flags or environment checks - Prerequisites not met - Platform-specific tests - Temporary test disabling with clear reason **Constructor:** ```typescript new Skip(reason?: string) ``` **Properties:** - [readonly] `reason?`: `string` — Human-readable reason for skipping. When provided, this reason is displayed in test reports. If not provided, defaults to `undefined` (the error message will still show "Skipped"). **Example:** Skip based on environment ```ts import { scenario } from "@probitas/builder"; import { Skip } from "@probitas/runner"; const def = scenario("Production Only") .step("Check environment", () => { if (Deno.env.get("ENV") !== "production") { throw new Skip("Only runs in production"); } }) .step("Production test", () => { console.log("Running in production"); }) .build(); console.log(def.name); ``` Skip based on resource availability ```ts import { scenario } from "@probitas/builder"; import { Skip } from "@probitas/runner"; const Database = { connect: async () => ({ query: (sql: string) => sql }) }; const def = scenario("Database Test") .resource("db", async () => { try { return await Database.connect(); } catch { throw new Skip("Database not available"); } }) .step("Query data", (ctx) => ctx.resources.db.query("SELECT 1")) .build(); console.log(def.name); ``` Skip with feature flag ```ts import { scenario } from "@probitas/builder"; import { Skip } from "@probitas/runner"; const def = scenario("Beta Feature") .step("Check feature flag", (ctx) => { if (!ctx.store.get("betaEnabled")) { throw new Skip("Beta feature not enabled"); } }) .build(); console.log(def.name); ``` --- ### `TimeError` ```typescript class TimeError extends Error ``` Represents an error when trying to execute an invalid operation on fake time, given the state fake time is in. **Constructor:** ```typescript new TimeError(message: string) ``` **Example:** Usage ```ts import { FakeTime, TimeError } from "@std/testing/time"; import { assertThrows } from "@std/assert"; assertThrows(() => { const time = new FakeTime(); time.restore(); time.restore(); }, TimeError); ``` --- ### `FakeTime` ```typescript class FakeTime ``` Overrides the real Date object and timer functions with fake ones that can be controlled through the fake time instance. Note: there is no setter for the `start` property, as it cannot be changed after initialization. **Constructor:** ```typescript new FakeTime(start?: number | string | Date | null, options?: FakeTimeOptions) ``` **Methods:** ```typescript [Symbol.dispose](): unknown ``` Restores real time. ```typescript static restore(): unknown ``` Restores real time. ```typescript static restoreFor(): unknown ``` Restores real time temporarily until callback returns and resolves. ```typescript now(): unknown ``` The number of milliseconds elapsed since the epoch (January 1, 1970 00:00:00 UTC) for the fake time. ```typescript now(): unknown ``` Set the current time. It will call any functions waiting to be called between the current and new fake time. If the timer callback throws, time will stop advancing forward beyond that timer. ```typescript start(): unknown ``` The initial number of milliseconds elapsed since the epoch (January 1, 1970 00:00:00 UTC) for the fake time. ```typescript delay(): unknown ``` Resolves after the given number of milliseconds using real time. ```typescript runMicrotasks(): unknown ``` Runs all pending microtasks. ```typescript tick(): unknown ``` Adds the specified number of milliseconds to the fake time. This will call any functions waiting to be called between the current and new fake time. ```typescript tickAsync(): unknown ``` Runs all pending microtasks then adds the specified number of milliseconds to the fake time. This will call any functions waiting to be called between the current and new fake time. ```typescript next(): unknown ``` Advances time to when the next scheduled timer is due. If there are no pending timers, time will not be changed. ```typescript nextAsync(): unknown ``` Runs all pending microtasks then advances time to when the next scheduled timer is due. If there are no pending timers, time will not be changed. ```typescript runAll(): unknown ``` Advances time forward to the next due timer until there are no pending timers remaining. If the timers create additional timers, they will be run too. If there is an interval, time will keep advancing forward until the interval is cleared. ```typescript runAllAsync(): unknown ``` Advances time forward to the next due timer until there are no pending timers remaining. If the timers create additional timers, they will be run too. If there is an interval, time will keep advancing forward until the interval is cleared. Runs all pending microtasks before each timer. ```typescript restore(): unknown ``` Restores time related global functions to their original state. **Example:** Usage ```ts import { assertSpyCalls, spy, } from "@std/testing/mock"; import { FakeTime } from "@std/testing/time"; function secondInterval(cb: () => void): number { return setInterval(cb, 1000); } Deno.test("secondInterval calls callback every second and stops after being cleared", () => { using time = new FakeTime(); const cb = spy(); const intervalId = secondInterval(cb); assertSpyCalls(cb, 0); time.tick(500); assertSpyCalls(cb, 0); time.tick(500); assertSpyCalls(cb, 1); time.tick(3500); assertSpyCalls(cb, 4); clearInterval(intervalId); time.tick(1000); assertSpyCalls(cb, 4); }); ``` --- ### `MockError` ```typescript class MockError extends Error ``` An error related to spying on a function or instance method. **Constructor:** ```typescript new MockError(message: string) ``` **Example:** Usage ```ts import { MockError, spy } from "@std/testing/mock"; import { assertThrows } from "@std/assert"; assertThrows(() => { spy({} as any, "no-such-method"); }, MockError); ``` --- ### `UnimplementedError` ```typescript class UnimplementedError extends Error ``` Error indicating that this part is unimplemented. **Constructor:** ```typescript new UnimplementedError(_: unknown) ``` --- ### `UnreachableError` ```typescript class UnreachableError extends Error ``` Error indicating that this part is unreachable. **Constructor:** ```typescript new UnreachableError(args: unknown[]) ``` **Properties:** - [readonly] `args`: `unknown[]` --- ## Interfaces ### `DelayOptions` ```typescript interface DelayOptions ``` Options for {@linkcode delay}. **Properties:** - `signal?`: `AbortSignal` — Signal used to abort the delay. - `persistent?`: `boolean` — Indicates whether the process should continue to run as long as the timer exists. --- ### `FakeTimeOptions` ```typescript interface FakeTimeOptions ``` The option for {@linkcode FakeTime} **Properties:** - `advanceRate`: `number` — The rate relative to real time at which fake time is updated. By default time only moves forward through calling tick or setting now. Set to 1 to have the fake time automatically tick forward at the same rate in milliseconds as real time. - `advanceFrequency?`: `number` — The frequency in milliseconds at which fake time is updated. If advanceRate is set, we will update the time every 10 milliseconds by default. --- ### `SpyCall` ```typescript interface SpyCall ``` Call information recorded by a spy. **Properties:** - `args`: `Args` — Arguments passed to a function when called. - `returned?`: `Return` — The value that was returned by a function. - `error?`: `Error` — The error value that was thrown by a function. - `self?`: `Self` — The instance that a method was called on. --- ### `Spy` ```typescript interface Spy ``` A function or instance method wrapper that records all calls made to it. **Properties:** - `original`: `(this: Self, _: Args) => unknown` — The function that is being spied on. - `calls`: `SpyCall[]` — Information about calls made to the function or instance method. - `restored`: `boolean` — Whether or not the original instance method has been restored. **Methods:** ```typescript restore(): void ``` If spying on an instance method, this restores the original instance method. --- ### `MethodSpy` ```typescript interface MethodSpy extends Spy, Disposable ``` An instance method wrapper that records all calls made to it. --- ### `ConstructorSpy` ```typescript interface ConstructorSpy ``` A constructor wrapper that records all calls made to it. **Properties:** - `original`: `(_: Args) => unknown` — The function that is being spied on. - `calls`: `SpyCall[]` — Information about calls made to the function or instance method. - `restored`: `boolean` — Whether or not the original instance method has been restored. **Methods:** ```typescript restore(): void ``` If spying on an instance method, this restores the original instance method. --- ### `Stub` ```typescript interface Stub extends MethodSpy ``` An instance method replacement that records all calls made to it. **Properties:** - `fake`: `(this: Self, _: Args) => unknown` — The function that is used instead of the original. --- ### `ExpectedSpyCall` ```typescript interface ExpectedSpyCall ``` Call information recorded by a spy. **Properties:** - `args?`: `[unknown, unknown]` — Arguments passed to a function when called. - `self?`: `Self` — The instance that a method was called on. - `returned?`: `Return` — The value that was returned by a function. If you expect a promise to reject, expect error instead. - `error?`: `{ Class?: (_: any[]) => unknown; msgIncludes?: string }` — The expected thrown error. --- ### `Outdent` ```typescript interface Outdent ``` **Methods:** ```typescript string(str: string): string ``` Remove indentation from a string --- ### `Options` ```typescript interface Options ``` **Properties:** - `trimLeadingNewline?`: `boolean` - `trimTrailingNewline?`: `boolean` - `newline?`: `string | null` — Normalize all newlines in the template literal to this value. If `null`, newlines are left untouched. Newlines that get normalized are '\r\n', '\r', and '\n'. Newlines within interpolated values are *never* normalized. Although intended for normalizing to '\n' or '\r\n', you can also set to any string; for example ' '. --- ## Functions ### `scenario` ```typescript function scenario(name: string, options?: ScenarioOptions): ScenarioBuilderInit ``` Create a new scenario builder with a fluent API. This is the primary entry point for defining scenarios. It returns a builder that provides a type-safe, chainable API for constructing test scenarios. **Parameters:** - `name`: `string` — - Human-readable scenario name (shown in test reports) - `options`: `ScenarioOptions` (optional) — - Optional configuration for tags, timeouts, and retry behavior **Returns:** `ScenarioBuilderInit` New {@linkcode ScenarioBuilderInit} instance ready for chaining **Example:** Basic scenario with type-safe step chaining ```ts import { scenario } from "@probitas/builder"; // Mock user service for example const createUser = (_data: { email: string }) => Promise.resolve({ id: "user-123" }); const verifyEmail = (_userId: string) => Promise.resolve(); export default scenario("User Registration") .step("Create user", async () => { const user = await createUser({ email: "test@example.com" }); return { userId: user.id }; }) .step("Verify email", async (ctx) => { // ctx.previous is typed as { userId: string } await verifyEmail(ctx.previous.userId); }) .build(); ``` Scenario with tags for filtering ```ts import { scenario } from "@probitas/builder"; scenario("Payment Integration", { tags: ["integration", "payment", "slow"], stepOptions: { timeout: 60000 } // 1 minute timeout for all steps }) .step("Process payment", async () => { return { success: true }; }) .build(); // Run with: probitas run -s "tag:payment" ``` Scenario with resources and setup ```ts import { scenario } from "@probitas/builder"; // Mock Database for example const Database = { connect: () => Promise.resolve({ rollback: () => {}, insert: (_data: { id: number }) => {}, query: (_sql: string) => [{ id: 1 }], }), }; scenario("Database Test") .resource("db", async () => await Database.connect()) .setup((ctx) => { // Run migrations return () => ctx.resources.db.rollback(); }) .step("Insert data", (ctx) => ctx.resources.db.insert({ id: 1 })) .step("Query data", (ctx) => ctx.resources.db.query("SELECT * FROM users")) .build(); ``` --- ### `expect` (11 overloads) **Overload 1:** ```typescript function expect( value: NotAny, ): HttpResponseExpectation ``` Unified expect function that dispatches to the appropriate expectation function based on the type of the input object. **Overload 2:** ```typescript function expect( value: NotAny, ): ConnectRpcResponseExpectation ``` **Overload 3:** ```typescript function expect( value: NotAny, ): GraphqlResponseExpectation ``` **Overload 4:** ```typescript function expect( value: NotAny, ): SqlQueryResultExpectation ``` **Overload 5:** ```typescript function expect(value: NotAny): DenoKvExpectation ``` **Overload 6:** ```typescript function expect(value: NotAny): RedisExpectation ``` **Overload 7:** ```typescript function expect(value: NotAny): MongoExpectation ``` **Overload 8:** ```typescript function expect( value: NotAny, ): RabbitMqExpectation ``` **Overload 9:** ```typescript function expect(value: NotAny): SqsExpectation ``` **Overload 10:** ```typescript function expect(value: any): AnythingExpectation ``` **Overload 11:** ```typescript function expect(value: unknown): unknown ``` --- ### `mockSession` (3 overloads) **Overload 1:** ```typescript function mockSession(): number ``` Creates a session that tracks all mocks created before it's restored. If a callback is provided, it restores all mocks created within it. **Overload 2:** ```typescript function mockSession( func: (this: Self, _: Args) => unknown, ): (this: Self, _: Args) => unknown ``` Creates a session that tracks all mocks created before it's restored. If a callback is provided, it restores all mocks created within it. **Overload 3:** ```typescript function mockSession( func?: (this: Self, _: Args) => unknown, ): number | unknown ``` --- ### `mockSessionAsync` ```typescript function mockSessionAsync( func: (this: Self, _: Args) => unknown, ): (this: Self, _: Args) => unknown ``` Creates an async session that tracks all mocks created before the promise resolves. **Parameters:** - `func`: `(this: Self, _: Args) => unknown` — The function. **Returns:** `(this: Self, _: Args) => unknown` The return value of the function. **Example:** Usage ```ts import { mockSessionAsync, restore, stub } from "@std/testing/mock"; import { assertEquals, assertNotEquals } from "@std/assert"; const setTimeout = globalThis.setTimeout; const session = mockSessionAsync(async () => { stub(globalThis, "setTimeout"); assertNotEquals(globalThis.setTimeout, setTimeout); }); await session(); assertEquals(globalThis.setTimeout, setTimeout); // stub is restored ``` --- ### `restore` ```typescript function restore(id?: number): void ``` Restores all mocks registered in the current session that have not already been restored. If an id is provided, it will restore all mocks registered in the session associed with that id that have not already been restored. **Parameters:** - `id`: `number` (optional) — The id of the session to restore. If not provided, all mocks registered in the current session are restored. **Returns:** `void` **Example:** Usage ```ts import { mockSession, restore, stub } from "@std/testing/mock"; import { assertEquals, assertNotEquals } from "@std/assert"; const setTimeout = globalThis.setTimeout; stub(globalThis, "setTimeout"); assertNotEquals(globalThis.setTimeout, setTimeout); restore(); assertEquals(globalThis.setTimeout, setTimeout); ``` --- ### `spy` (5 overloads) **Overload 1:** ```typescript function spy(): Spy ``` Creates a spy function. **Overload 2:** ```typescript function spy( func: (this: Self, _: Args) => unknown, ): Spy ``` Create a spy function with the given implementation. **Overload 3:** ```typescript function spy( constructor: (_: Args) => unknown, ): ConstructorSpy ``` Create a spy constructor. **Overload 4:** ```typescript function spy( self: Self, property: Prop, ): MethodSpy, GetReturnFromProp> ``` Wraps a instance method with a Spy. **Overload 5:** ```typescript function spy( funcOrConstOrSelf?: unknown | unknown | Self, property?: keyof Self, ): SpyLike ``` --- ### `stub` (3 overloads) **Overload 1:** ```typescript function stub( self: Self, property: Prop, ): Stub, GetReturnFromProp> ``` Replaces an instance method with a Stub with empty implementation. **Overload 2:** ```typescript function stub( self: Self, property: Prop, func: (this: Self, _: GetParametersFromProp) => unknown, ): Stub, GetReturnFromProp> ``` Replaces an instance method with a Stub with the given implementation. **Overload 3:** ```typescript function stub( self: Self, property: keyof Self, func?: (this: Self, _: Args) => unknown, ): Stub ``` --- ### `assertSpyCalls` ```typescript function assertSpyCalls( spy: SpyLike, expectedCalls: number, ): void ``` Asserts that a spy is called as much as expected and no more. **Parameters:** - `spy`: `SpyLike` — The spy to check - `expectedCalls`: `number` — The number of the expected calls. **Returns:** `void` **Example:** Usage ```ts import { assertSpyCalls, spy } from "@std/testing/mock"; const func = spy(); func(); func(); assertSpyCalls(func, 2); ``` --- ### `assertSpyCall` ```typescript function assertSpyCall( spy: SpyLike, callIndex: number, expected?: ExpectedSpyCall, ): void ``` Asserts that a spy is called as expected. **Parameters:** - `spy`: `SpyLike` — The spy to check - `callIndex`: `number` — The index of the call to check - `expected`: `ExpectedSpyCall` (optional) — The expected spy call. **Returns:** `void` **Example:** Usage ```ts import { assertSpyCall, spy } from "@std/testing/mock"; const func = spy((a: number, b: number) => a + b); func(3, 4); func(5, 6); // asserts each call made to the spy function. assertSpyCall(func, 0, { args: [3, 4], returned: 7 }); assertSpyCall(func, 1, { args: [5, 6], returned: 11 }); ``` --- ### `assertSpyCallAsync` ```typescript async function assertSpyCallAsync( spy: SpyLike>, callIndex: number, expected?: ExpectedSpyCall | Return>, ): Promise ``` Asserts that an async spy is called as expected. **Parameters:** - `spy`: `SpyLike>` — The spy to check - `callIndex`: `number` — The index of the call to check - `expected`: `ExpectedSpyCall | Return>` (optional) — The expected spy call. **Returns:** `Promise` **Example:** Usage ```ts import { assertSpyCallAsync, spy } from "@std/testing/mock"; const func = spy((a: number, b: number) => new Promise((resolve) => { setTimeout(() => resolve(a + b), 100) })); await func(3, 4); await func(5, 6); // asserts each call made to the spy function. await assertSpyCallAsync(func, 0, { args: [3, 4], returned: 7 }); await assertSpyCallAsync(func, 1, { args: [5, 6], returned: 11 }); ``` --- ### `assertSpyCallArg` ```typescript function assertSpyCallArg( spy: SpyLike, callIndex: number, argIndex: number, expected: ExpectedArg, ): ExpectedArg ``` Asserts that a spy is called with a specific arg as expected. **Parameters:** - `spy`: `SpyLike` — The spy to check. - `callIndex`: `number` — The index of the call to check. - `argIndex`: `number` — The index of the arguments to check. - `expected`: `ExpectedArg` — The expected argument. **Returns:** `ExpectedArg` The actual argument. **Example:** Usage ```ts import { assertSpyCallArg, spy } from "@std/testing/mock"; const func = spy((a: number, b: number) => a + b); func(3, 4); func(5, 6); // asserts each call made to the spy function. assertSpyCallArg(func, 0, 0, 3); assertSpyCallArg(func, 0, 1, 4); assertSpyCallArg(func, 1, 0, 5); assertSpyCallArg(func, 1, 1, 6); ``` --- ### `assertSpyCallArgs` (4 overloads) **Overload 1:** ```typescript function assertSpyCallArgs( spy: SpyLike, callIndex: number, expected: ExpectedArgs, ): ExpectedArgs ``` Asserts that an spy is called with a specific range of args as expected. If a start and end index is not provided, the expected will be compared against all args. If a start is provided without an end index, the expected will be compared against all args from the start index to the end. The end index is not included in the range of args that are compared. **Overload 2:** ```typescript function assertSpyCallArgs( spy: SpyLike, callIndex: number, argsStart: number, expected: ExpectedArgs, ): ExpectedArgs ``` Asserts that an spy is called with a specific range of args as expected. If a start and end index is not provided, the expected will be compared against all args. If a start is provided without an end index, the expected will be compared against all args from the start index to the end. The end index is not included in the range of args that are compared. **Overload 3:** ```typescript function assertSpyCallArgs( spy: SpyLike, callIndex: number, argsStart: number, argsEnd: number, expected: ExpectedArgs, ): ExpectedArgs ``` Asserts that an spy is called with a specific range of args as expected. If a start and end index is not provided, the expected will be compared against all args. If a start is provided without an end index, the expected will be compared against all args from the start index to the end. The end index is not included in the range of args that are compared. **Overload 4:** ```typescript function assertSpyCallArgs( spy: SpyLike, callIndex: number, argsStart?: number | ExpectedArgs, argsEnd?: number | ExpectedArgs, expected?: ExpectedArgs, ): ExpectedArgs ``` --- ### `returnsThis` ```typescript function returnsThis(): (this: Self, _: Args) => unknown ``` Creates a function that returns the instance the method was called on. **Returns:** `(this: Self, _: Args) => unknown` A function that returns the instance the method was called on. **Example:** Usage ```ts import { returnsThis } from "@std/testing/mock"; import { assertEquals } from "@std/assert"; const func = returnsThis(); const obj = { func }; assertEquals(obj.func(), obj); ``` --- ### `returnsArg` ```typescript function returnsArg( idx: number, ): (this: Self, _: Arg[]) => unknown ``` Creates a function that returns one of its arguments. **Parameters:** - `idx`: `number` — The index of the arguments to use. **Returns:** `(this: Self, _: Arg[]) => unknown` A function that returns one of its arguments. **Example:** Usage ```ts import { returnsArg } from "@std/testing/mock"; import { assertEquals } from "@std/assert"; const func = returnsArg(1); assertEquals(func(1, 2, 3), 2); ``` --- ### `returnsArgs` ```typescript function returnsArgs( _: unknown, end?: number, ): (this: Self, _: Args) => unknown ``` Creates a function that returns its arguments or a subset of them. If end is specified, it will return arguments up to but not including the end. **Parameters:** - `_`: `unknown` - `end`: `number` (optional) — The end index of the arguments to return. **Returns:** `(this: Self, _: Args) => unknown` A function that returns its arguments or a subset of them. **Example:** Usage ```ts import { returnsArgs } from "@std/testing/mock"; import { assertEquals } from "@std/assert"; const func = returnsArgs(); assertEquals(func(1, 2, 3), [1, 2, 3]); ``` --- ### `returnsNext` ```typescript function returnsNext( values: Iterable, ): (this: Self, _: Args) => unknown ``` Creates a function that returns the iterable values. Any iterable values that are errors will be thrown. **Parameters:** - `values`: `Iterable` — The iterable values **Returns:** `(this: Self, _: Args) => unknown` A function that returns the iterable values **Example:** Usage ```ts import { returnsNext } from "@std/testing/mock"; import { assertEquals, assertThrows } from "@std/assert"; const func = returnsNext([1, 2, new Error("foo"), 3]); assertEquals(func(), 1); assertEquals(func(), 2); assertThrows(() => func(), Error, "foo"); assertEquals(func(), 3); ``` --- ### `resolvesNext` ```typescript function resolvesNext( iterable: Iterable> | AsyncIterable>, ): (this: Self, _: Args) => unknown ``` Creates a function that resolves the awaited iterable values. Any awaited iterable values that are errors will be thrown. **Parameters:** - `iterable`: `Iterable> | AsyncIterable>` — The iterable to use **Returns:** `(this: Self, _: Args) => unknown` A function that resolves the awaited iterable values **Example:** Usage ```ts import { resolvesNext } from "@std/testing/mock"; import { assertEquals, assertRejects } from "@std/assert"; const func = resolvesNext([1, 2, new Error("foo"), 3]); assertEquals(await func(), 1); assertEquals(await func(), 2); assertRejects(() => func(), Error, "foo"); assertEquals(await func(), 3); ``` --- ### `alter` ```typescript function alter(fn: () => unknown, alt: E): T ``` Alter the error of a function if an error is thrown. **Parameters:** - `fn`: `() => unknown` — - The function to execute. - `alt`: `E` — - The value to throw if an error is thrown. **Returns:** `T` The result of the function. **Example:** ```ts import { assertThrows } from "@std/assert"; import { alter } from "@core/errorutil/alter"; console.log(alter(() => 1, "err2")); // 1 assertThrows(() => alter(() => { throw "err1" }, "err2"), "err2"); // "err2" is thrown ``` --- ### `alterElse` ```typescript function alterElse( fn: () => unknown, elseFn: (err: unknown) => unknown, ): T ``` Alter the error of a function if an error is thrown. **Parameters:** - `fn`: `() => unknown` — - The function to execute. - `elseFn`: `(err: unknown) => unknown` **Returns:** `T` The result of the function. **Example:** ```ts import { assertThrows } from "@std/assert"; import { alterElse } from "@core/errorutil/alter-else"; console.log(alterElse(() => 1, () => "err")); // 1 assertThrows(() => alterElse(() => { throw "err" }, (err) => "new " + err), "new err"); // "new err" is thrown ``` --- ### `attempt` ```typescript function attempt(fn: () => unknown): Result ``` Attempt to execute a function and return a Result. **Parameters:** - `fn`: `() => unknown` — - The function to execute. **Returns:** `Result` A Result where T is the return type of the function and E is the error type. **Example:** ```ts import { attempt } from "@core/errorutil/attempt"; console.log(attempt(() => 1)); // [undefined, 1] console.log(attempt(() => { throw "err" })); // ["err", undefined] ``` --- ### `toErrorObject` ```typescript function toErrorObject(err: Error): ErrorObject ``` Convert an error to an error object **Parameters:** - `err`: `Error` **Returns:** `ErrorObject` --- ### `fromErrorObject` ```typescript function fromErrorObject(obj: ErrorObject): Error ``` Convert an error object to an error **Parameters:** - `obj`: `ErrorObject` **Returns:** `Error` --- ### `raise` ```typescript function raise(err: unknown): never ``` Throw an error. This is function thus can be used as an expression. ```typescript import { raise } from "@core/errorutil/raise"; const fn = () => raise(new Error("fail")); ``` **Parameters:** - `err`: `unknown` **Returns:** `never` --- ### `tryOr` ```typescript function tryOr(fn: () => unknown, orValue: T): T ``` Try to execute a function and return the result or a default value if an error occurs. ```ts import { tryOr } from "@core/errorutil/try-or"; console.log(tryOr(() => 1, 2)); // 1 console.log(tryOr(() => { throw "err"; }, 2)); // 2 ``` **Parameters:** - `fn`: `() => unknown` - `orValue`: `T` **Returns:** `T` --- ### `tryOrElse` ```typescript function tryOrElse(fn: () => unknown, elseFn: (err: unknown) => unknown): T ``` Try to execute a function and return the result or execute another function and return its result if an error occurs. ```ts import { tryOrElse } from "@core/errorutil/try-or-else"; console.log(tryOrElse(() => 1, () => 2)); // 1 console.log(tryOrElse(() => { throw "err" }, () => 2)); // 2 ``` **Parameters:** - `fn`: `() => unknown` - `elseFn`: `(err: unknown) => unknown` **Returns:** `T` --- ### `unimplemented` ```typescript function unimplemented(_: unknown): never ``` Function indicating that this part is unimplemented. For example, defining a mock object with `unimplemented` function should look like this: ```ts import { unimplemented } from "@core/errorutil/unimplemented"; type Service = { get(id: string): Promise; set(id: string, item: string): Promise; }; const _mock: Service = { get: () => unimplemented(), set: () => unimplemented(), }; ``` **Parameters:** - `_`: `unknown` **Returns:** `never` --- ### `unreachable` ```typescript function unreachable(_: never[]): never ``` Function indicating that this part is unreachable. For example, the following code passed type checking. ```ts import { unreachable } from "@core/errorutil/unreachable"; type Animal = "dog" | "cat"; function say(animal: Animal): void { switch (animal) { case "dog": console.log("dog"); break; case "cat": console.log("dog"); break; default: unreachable(animal); } } say("dog"); ``` But the following code because a case for "bird" is missing. ```ts import { unreachable } from "@core/errorutil/unreachable"; type Animal = "dog" | "cat" | "bird"; function say(animal: Animal): void { switch (animal) { case "dog": console.log("dog"); break; case "cat": console.log("dog"); break; default: { // The line below causes a type error if we uncomment it. // error: TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'never'. //unreachable(animal); } } } say("dog"); ``` **Parameters:** - `_`: `never[]` **Returns:** `never` --- ## Types ### `StepContext` ```typescript type StepContext

= Record> = StepContext & { previous: P; results: A; resources: R } ``` Execution context provided to steps, resources, and setup hooks. The context provides access to: - Previous step results with full type inference - All accumulated results as a typed tuple - Named resources registered with `.resource()` - Shared storage for cross-step communication - Abort signal for timeout and cancellation handling --- ### `ConnectRpcResponse` ```typescript type ConnectRpcResponse = ConnectRpcResponseSuccess | ConnectRpcResponseError | ConnectRpcResponseFailure ``` ConnectRPC response union type. Use `processed` to distinguish between server responses and failures: - `processed === true`: Server responded (Success or Error) - `processed === false`: Request failed (Failure) Use `ok` to check for success: - `ok === true`: Success (statusCode === 0) - `ok === false`: Error or Failure --- ### `DenoKvResult` ```typescript type DenoKvResult = DenoKvGetResult | DenoKvSetResult | DenoKvDeleteResult | DenoKvListResult | DenoKvAtomicResult ``` Union of all Deno KV result types. --- ### `GraphqlResponse` ```typescript type GraphqlResponse = GraphqlResponseSuccess | GraphqlResponseError | GraphqlResponseFailure ``` GraphQL response union type. Use `processed` to distinguish between server responses and failures: - `processed === true`: Server responded (Success or Error) - `processed === false`: Request failed (Failure) Use `ok` to check for success: - `ok === true`: Success (no errors) - `ok === false`: Error or Failure --- ### `HttpResponse` ```typescript type HttpResponse = HttpResponseSuccess | HttpResponseError | HttpResponseFailure ``` HTTP response union type representing all possible response states. - **Success (2xx)**: `processed: true, ok: true, error: null` - **Error (4xx/5xx)**: `processed: true, ok: false, error: HttpError` - **Failure (network error)**: `processed: false, ok: false, error: Error` --- ### `MongoResult` ```typescript type MongoResult = MongoFindResult | MongoInsertOneResult | MongoInsertManyResult | MongoUpdateResult | MongoDeleteResult | MongoFindOneResult | MongoCountResult ``` Union of all MongoDB result types. --- ### `RabbitMqResult` ```typescript type RabbitMqResult = RabbitMqPublishResult | RabbitMqConsumeResult | RabbitMqAckResult | RabbitMqQueueResult | RabbitMqExchangeResult ``` Union of all RabbitMQ result types. --- ### `RedisResult` ```typescript type RedisResult = RedisCommonResult | RedisGetResult | RedisSetResult | RedisCountResult | RedisArrayResult | RedisHashResult ``` Union of all Redis result types. --- ### `SqlQueryResult` ```typescript type SqlQueryResult = SqlQueryResultSuccess | SqlQueryResultError | SqlQueryResultFailure ``` SQL query result union type representing all possible result states. - **Success**: `processed: true, ok: true, error: null` - **Error**: `processed: true, ok: false, error: SqlError` - **Failure**: `processed: false, ok: false, error: SqlConnectionError` --- ### `SqsResult` ```typescript type SqsResult = SqsSendResult | SqsSendBatchResult | SqsReceiveResult | SqsDeleteResult | SqsDeleteBatchResult | SqsEnsureQueueResult | SqsDeleteQueueResult ``` Union type of all SQS result types. --- ### `SpyLike` ```typescript type SpyLike = Spy | ConstructorSpy ``` SpyLink object type. --- ### `Success` ```typescript type Success = [undefined, T] ``` --- ### `Failure` ```typescript type Failure = [E, undefined] ``` --- ### `Result` ```typescript type Result = Success | Failure ``` --- ### `ErrorObject` ```typescript type ErrorObject = { proto: string; name: string; message: string; stack?: string; attributes: Record; } ``` An error object is a serializable representation of an error --- ## Variables ### `isErrorObject` ```typescript const isErrorObject: (x: unknown) => unknown ``` Check if a value is an error object --- ### `outdent` ```typescript const outdent: Outdent ``` --- ## Related Links ### This Package - [`ConnectRpcResponse`](https://probitas-test.github.io/documents/api/probitas#ConnectRpcResponse) - [`ConstructorSpy`](https://probitas-test.github.io/documents/api/probitas#ConstructorSpy) - [`DenoKvResult`](https://probitas-test.github.io/documents/api/probitas#DenoKvResult) - [`ErrorObject`](https://probitas-test.github.io/documents/api/probitas#ErrorObject) - [`ExpectedSpyCall`](https://probitas-test.github.io/documents/api/probitas#ExpectedSpyCall) - [`Failure`](https://probitas-test.github.io/documents/api/probitas#Failure) - [`FakeTimeOptions`](https://probitas-test.github.io/documents/api/probitas#FakeTimeOptions) - [`GraphqlResponse`](https://probitas-test.github.io/documents/api/probitas#GraphqlResponse) - [`HttpResponse`](https://probitas-test.github.io/documents/api/probitas#HttpResponse) - [`MethodSpy`](https://probitas-test.github.io/documents/api/probitas#MethodSpy) - [`MongoResult`](https://probitas-test.github.io/documents/api/probitas#MongoResult) - [`Outdent`](https://probitas-test.github.io/documents/api/probitas#Outdent) - [`RabbitMqResult`](https://probitas-test.github.io/documents/api/probitas#RabbitMqResult) - [`RedisResult`](https://probitas-test.github.io/documents/api/probitas#RedisResult) - [`Result`](https://probitas-test.github.io/documents/api/probitas#Result) - [`Spy`](https://probitas-test.github.io/documents/api/probitas#Spy) - [`SpyCall`](https://probitas-test.github.io/documents/api/probitas#SpyCall) - [`SpyLike`](https://probitas-test.github.io/documents/api/probitas#SpyLike) - [`SqlQueryResult`](https://probitas-test.github.io/documents/api/probitas#SqlQueryResult) - [`SqsResult`](https://probitas-test.github.io/documents/api/probitas#SqsResult) - [`StepContext`](https://probitas-test.github.io/documents/api/probitas#StepContext) - [`Stub`](https://probitas-test.github.io/documents/api/probitas#Stub) - [`Success`](https://probitas-test.github.io/documents/api/probitas#Success) ### Other Packages - [`AnythingExpectation`](https://probitas-test.github.io/documents/api/expect#AnythingExpectation) (@probitas/expect) - [`ConnectRpcResponseError`](https://probitas-test.github.io/documents/api/expect#ConnectRpcResponseError) (@probitas/expect) - [`ConnectRpcResponseExpectation`](https://probitas-test.github.io/documents/api/expect#ConnectRpcResponseExpectation) (@probitas/expect) - [`ConnectRpcResponseFailure`](https://probitas-test.github.io/documents/api/expect#ConnectRpcResponseFailure) (@probitas/expect) - [`ConnectRpcResponseSuccess`](https://probitas-test.github.io/documents/api/expect#ConnectRpcResponseSuccess) (@probitas/expect) - [`DenoKvAtomicResult`](https://probitas-test.github.io/documents/api/expect#DenoKvAtomicResult) (@probitas/expect) - [`DenoKvDeleteResult`](https://probitas-test.github.io/documents/api/expect#DenoKvDeleteResult) (@probitas/expect) - [`DenoKvExpectation`](https://probitas-test.github.io/documents/api/expect#DenoKvExpectation) (@probitas/expect) - [`DenoKvGetResult`](https://probitas-test.github.io/documents/api/expect#DenoKvGetResult) (@probitas/expect) - [`DenoKvListResult`](https://probitas-test.github.io/documents/api/expect#DenoKvListResult) (@probitas/expect) - [`DenoKvSetResult`](https://probitas-test.github.io/documents/api/expect#DenoKvSetResult) (@probitas/expect) - [`GraphqlResponseError`](https://probitas-test.github.io/documents/api/expect#GraphqlResponseError) (@probitas/expect) - [`GraphqlResponseExpectation`](https://probitas-test.github.io/documents/api/expect#GraphqlResponseExpectation) (@probitas/expect) - [`GraphqlResponseFailure`](https://probitas-test.github.io/documents/api/expect#GraphqlResponseFailure) (@probitas/expect) - [`GraphqlResponseSuccess`](https://probitas-test.github.io/documents/api/expect#GraphqlResponseSuccess) (@probitas/expect) - [`HttpResponseError`](https://probitas-test.github.io/documents/api/expect#HttpResponseError) (@probitas/expect) - [`HttpResponseExpectation`](https://probitas-test.github.io/documents/api/expect#HttpResponseExpectation) (@probitas/expect) - [`HttpResponseFailure`](https://probitas-test.github.io/documents/api/expect#HttpResponseFailure) (@probitas/expect) - [`HttpResponseSuccess`](https://probitas-test.github.io/documents/api/expect#HttpResponseSuccess) (@probitas/expect) - [`MongoCountResult`](https://probitas-test.github.io/documents/api/expect#MongoCountResult) (@probitas/expect) - [`MongoDeleteResult`](https://probitas-test.github.io/documents/api/expect#MongoDeleteResult) (@probitas/expect) - [`MongoExpectation`](https://probitas-test.github.io/documents/api/expect#MongoExpectation) (@probitas/expect) - [`MongoFindOneResult`](https://probitas-test.github.io/documents/api/expect#MongoFindOneResult) (@probitas/expect) - [`MongoFindResult`](https://probitas-test.github.io/documents/api/expect#MongoFindResult) (@probitas/expect) - [`MongoInsertManyResult`](https://probitas-test.github.io/documents/api/expect#MongoInsertManyResult) (@probitas/expect) - [`MongoInsertOneResult`](https://probitas-test.github.io/documents/api/expect#MongoInsertOneResult) (@probitas/expect) - [`MongoUpdateResult`](https://probitas-test.github.io/documents/api/expect#MongoUpdateResult) (@probitas/expect) - [`RabbitMqAckResult`](https://probitas-test.github.io/documents/api/expect#RabbitMqAckResult) (@probitas/expect) - [`RabbitMqConsumeResult`](https://probitas-test.github.io/documents/api/expect#RabbitMqConsumeResult) (@probitas/expect) - [`RabbitMqExchangeResult`](https://probitas-test.github.io/documents/api/expect#RabbitMqExchangeResult) (@probitas/expect) - [`RabbitMqExpectation`](https://probitas-test.github.io/documents/api/expect#RabbitMqExpectation) (@probitas/expect) - [`RabbitMqPublishResult`](https://probitas-test.github.io/documents/api/expect#RabbitMqPublishResult) (@probitas/expect) - [`RabbitMqQueueResult`](https://probitas-test.github.io/documents/api/expect#RabbitMqQueueResult) (@probitas/expect) - [`RedisArrayResult`](https://probitas-test.github.io/documents/api/expect#RedisArrayResult) (@probitas/expect) - [`RedisCommonResult`](https://probitas-test.github.io/documents/api/expect#RedisCommonResult) (@probitas/expect) - [`RedisCountResult`](https://probitas-test.github.io/documents/api/expect#RedisCountResult) (@probitas/expect) - [`RedisExpectation`](https://probitas-test.github.io/documents/api/expect#RedisExpectation) (@probitas/expect) - [`RedisGetResult`](https://probitas-test.github.io/documents/api/expect#RedisGetResult) (@probitas/expect) - [`RedisHashResult`](https://probitas-test.github.io/documents/api/expect#RedisHashResult) (@probitas/expect) - [`RedisSetResult`](https://probitas-test.github.io/documents/api/expect#RedisSetResult) (@probitas/expect) - [`ScenarioOptions`](https://probitas-test.github.io/documents/api/scenario#ScenarioOptions) (@probitas/scenario) - [`SqlQueryResultError`](https://probitas-test.github.io/documents/api/expect#SqlQueryResultError) (@probitas/expect) - [`SqlQueryResultExpectation`](https://probitas-test.github.io/documents/api/expect#SqlQueryResultExpectation) (@probitas/expect) - [`SqlQueryResultFailure`](https://probitas-test.github.io/documents/api/expect#SqlQueryResultFailure) (@probitas/expect) - [`SqlQueryResultSuccess`](https://probitas-test.github.io/documents/api/expect#SqlQueryResultSuccess) (@probitas/expect) - [`SqsDeleteBatchResult`](https://probitas-test.github.io/documents/api/expect#SqsDeleteBatchResult) (@probitas/expect) - [`SqsDeleteQueueResult`](https://probitas-test.github.io/documents/api/expect#SqsDeleteQueueResult) (@probitas/expect) - [`SqsDeleteResult`](https://probitas-test.github.io/documents/api/expect#SqsDeleteResult) (@probitas/expect) - [`SqsEnsureQueueResult`](https://probitas-test.github.io/documents/api/expect#SqsEnsureQueueResult) (@probitas/expect) - [`SqsExpectation`](https://probitas-test.github.io/documents/api/expect#SqsExpectation) (@probitas/expect) - [`SqsReceiveResult`](https://probitas-test.github.io/documents/api/expect#SqsReceiveResult) (@probitas/expect) - [`SqsSendBatchResult`](https://probitas-test.github.io/documents/api/expect#SqsSendBatchResult) (@probitas/expect) - [`SqsSendResult`](https://probitas-test.github.io/documents/api/expect#SqsSendResult) (@probitas/expect) ### Built-in Types - [`AsyncIterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols) - [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) - [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) - [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol) - [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) - [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type) --- *Last updated: 2026-01-12*