Skip to content

@temporal-contract/testing


@temporal-contract/testing / activity

activity ​

Type Aliases ​

RunActivityHandlerError ​

ts
type RunActivityHandlerError<TActivity> = TActivity extends object ? ContractErrorUnion<TErrors> | ApplicationFailure : ApplicationFailure;

Defined in: activity.ts:166

Error channel surfaced by runActivityHandler: the activity's declared errors rehydrated to their consumer-side (post-transform) shape — exactly what the workflow-side proxy would produce — plus ApplicationFailure for everything else that crossed the boundary (technical failures returned by the implementation, and the worker's terminal validation failures: ActivityInputValidationError, ActivityOutputValidationError, ContractErrorDataValidationError — all ApplicationFailure subclasses, discriminable via failure.type).

Type Parameters ​

Type Parameter
TActivity extends ActivityDefinition

RunActivityHandlerOptions ​

ts
type RunActivityHandlerOptions<TActivity, TOutput, TError> = object;

Defined in: activity.ts:175

Options for runActivityHandler.

Type Parameters ​

Type Parameter
TActivity extends ActivityDefinition
TOutput
TError

Properties ​

PropertyTypeDefault valueDescriptionDefined in
activityName?string"activity"Diagnostic name used in validation-error messages (mirrors the flat runtime activity name).activity.ts:193
env?MockActivityEnvironmentundefinedReuse a prepared MockActivityEnvironment — same semantics as RunActivityOptions.env.activity.ts:198
implementationRunActivityImplementation<TActivity, TOutput, TError>undefinedThe activity implementation under test — the same function you would pass to declareActivitiesHandler.activity.ts:180
inputClientInferInput<TActivity>undefinedThe activity input as a caller would send it (the wire value, in the input schema's pre-transform shape) — the handler parses it, exactly like production.activity.ts:186

RunActivityImplementation ​

ts
type RunActivityImplementation<TActivity, TOutput, TError> = (helpers, args) => AsyncResult<TOutput, TError>;

Defined in: activity.ts:66

Shape of the implementation accepted by runActivity and runActivityHandler — the same (helpers, args) => AsyncResult<...> shape declareActivitiesHandler expects — the input is on the helpers record too, so ({ errors, input }) => ... is the same call in one destructuring — with the output/error channels inferred from the function itself. The context helper is always empty here: implementations relying on middleware-injected context should be exercised through a worker instead.

Type Parameters ​

Type Parameter
TActivity extends ActivityDefinition
TOutput
TError

Parameters ​

ParameterType
helpers{ context: Record<never, never>; errors: ActivityErrorConstructorsOf<TActivity>; input: WorkerInferInput<TActivity>; }
helpers.contextRecord<never, never>
helpers.errorsActivityErrorConstructorsOf<TActivity>
helpers.inputWorkerInferInput<TActivity>
argsWorkerInferInput<TActivity>

Returns ​

AsyncResult<TOutput, TError>


RunActivityOptions ​

ts
type RunActivityOptions<TActivity, TOutput, TError> = object;

Defined in: activity.ts:78

Options for runActivity.

Type Parameters ​

Type Parameter
TActivity extends ActivityDefinition
TOutput
TError

Properties ​

PropertyTypeDescriptionDefined in
env?MockActivityEnvironmentReuse a prepared MockActivityEnvironment — pass one to observe heartbeats (env.on("heartbeat", ...)), trigger cancellation (env.cancel()), or customize the activity info. A fresh default environment is created when omitted.activity.ts:92
implementationRunActivityImplementation<TActivity, TOutput, TError>The activity implementation under test.activity.ts:80
inputWorkerInferInput<TActivity>The activity input, in the parsed shape the worker would hand the implementation.activity.ts:85

Functions ​

runActivity() ​

ts
function runActivity<TActivity, TOutput, TError>(definition, options): AsyncResult<TOutput, TError>;

Defined in: activity.ts:126

Execute a single activity implementation against its contract definition inside a MockActivityEnvironment, returning the implementation's AsyncResult untouched: Ok/Err flow through as-is, and an unanticipated throw (including a CancelledFailure from cancellation) surfaces on the defect channel.

This is the pure-logic tier: no input parse, no output validation, no contract-error wire conversion. A test that passes here can still fail at the production boundary (e.g. an Err whose data violates the declared schema) — cover that with runActivityHandler.

Type Parameters ​

Type Parameter
TActivity extends ActivityDefinition
TOutput
TError

Parameters ​

ParameterTypeDescription
definitionTActivityThe activity's contract definition (used to build the typed errors constructors handed to the implementation).
optionsRunActivityOptions<TActivity, TOutput, TError>See RunActivityOptions.

Returns ​

AsyncResult<TOutput, TError>

Example ​

ts
import { runActivity } from "@temporal-contract/testing/activity";

const result = await runActivity(
  orderContract.workflows.processOrder.activities.chargeCard,
  {
    implementation: chargeCard, // ({ errors, input }) => AsyncResult<...>
    input: { amount: 100 },
  },
);

await expect(result).toBeOk(); // with @unthrown/vitest matchers

runActivityHandler() ​

ts
function runActivityHandler<TActivity, TOutput, TError>(definition, options): AsyncResult<ClientInferOutput<TActivity>, RunActivityHandlerError<TActivity>>;

Defined in: activity.ts:244

Execute a single activity implementation through the realdeclareActivitiesHandler wrapping inside a MockActivityEnvironment, then classify the outcome the way a workflow-side caller would:

  • the wire input is parsed against the contract's input schema (an invalid input surfaces the production ActivityInputValidationError);
  • the implementation's Ok output is validated on the sending side and parsed on the receiving side, so a transforming output schema applies exactly once — and drift from the schema surfaces the production ActivityOutputValidationError;
  • a typed Err(errors.X(data)) is converted to its ApplicationFailure wire shape (type = error name, details[0] = data, details[1] = the provenance wire marker) and rehydrated back into the typed ContractError — the full wire round-trip;
  • contract misuse (an undeclared error name, or error data failing its declared schema) surfaces the production terminal ContractErrorDataValidationError instead of a green test;
  • an unanticipated throw stays on the defect channel.

Use runActivity for pure-logic unit tests of the implementation; use this when the test should be boundary-faithful — passing here means the same call succeeds through a real worker.

Type Parameters ​

Type Parameter
TActivity extends ActivityDefinition
TOutput
TError

Parameters ​

ParameterTypeDescription
definitionTActivityThe activity's contract definition.
optionsRunActivityHandlerOptions<TActivity, TOutput, TError>See RunActivityHandlerOptions.

Returns ​

AsyncResult<ClientInferOutput<TActivity>, RunActivityHandlerError<TActivity>>

Example ​

ts
import { runActivityHandler } from "@temporal-contract/testing/activity";

const result = await runActivityHandler(
  orderContract.workflows.processOrder.activities.chargeCard,
  {
    implementation: chargeCard,
    input: { amount: -1 },
  },
);

// The declared error crossed the wire and rehydrated as a typed error.
await expect(result).toBeErrTagged("@temporal-contract/ContractError");

Released under the MIT License.