Skip to content

Commit

Permalink
Merge branch 'main' into jack/step-ai-run-edit
Browse files Browse the repository at this point in the history
  • Loading branch information
jpwilliams committed Nov 13, 2024
2 parents a5dd6a4 + deec655 commit 1899d30
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 45 deletions.
2 changes: 1 addition & 1 deletion packages/inngest/src/next.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*/

import { type NextApiRequest, type NextApiResponse } from "next";
import { type NextRequest } from "next/server";
import { type NextRequest } from "next/server.js";
import {
InngestCommHandler,
type ServeHandlerOptions,
Expand Down
8 changes: 8 additions & 0 deletions packages/test/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# @inngest/test

## 0.1.1

### Patch Changes

- [#741](https://github.com/inngest/inngest-js/pull/741) [`6782497`](https://github.com/inngest/inngest-js/commit/67824978ddd3cab7b923555341a2fbfe4ae96280) Thanks [@jpwilliams](https://github.com/jpwilliams)! - Fix the first step in a run running twice

- [#741](https://github.com/inngest/inngest-js/pull/741) [`6782497`](https://github.com/inngest/inngest-js/commit/67824978ddd3cab7b923555341a2fbfe4ae96280) Thanks [@jpwilliams](https://github.com/jpwilliams)! - Fix immediate function/step failures not returning `error` correctly

## 0.1.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/test/jsr.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://jsr.io/schema/config-file.v1.json",
"name": "@inngest/test",
"description": "Tooling for testing Inngest functions.",
"version": "0.1.0",
"version": "0.1.1",
"include": [
"./src/**/*.ts"
],
Expand Down
2 changes: 1 addition & 1 deletion packages/test/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@inngest/test",
"version": "0.1.0",
"version": "0.1.1",
"description": "Tooling for testing Inngest functions.",
"main": "./index.js",
"types": "./index.d.ts",
Expand Down
80 changes: 57 additions & 23 deletions packages/test/src/InngestTestEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export namespace InngestTestEngine {
* TODO Potentially later allow many functions such that we can invoke and
* send events.
*/
function: InngestFunction.Any;
function: InngestFunction<any, any, any, any, any, any>;

/**
* The event payloads to send to the function. If none is given, an
Expand Down Expand Up @@ -91,6 +91,7 @@ export namespace InngestTestEngine {

export interface MockedStep {
id: string;
idIsHashed?: boolean;
handler: () => any;
}

Expand Down Expand Up @@ -209,33 +210,64 @@ export class InngestTestEngine {
*/
inlineOpts?: InngestTestEngine.ExecuteOptions<T>
): Promise<InngestTestRun.RunOutput> {
const { run } = await this.individualExecution(inlineOpts);
const output = await this.individualExecution(inlineOpts);

return run
.waitFor("function-resolved")
.then<InngestTestRun.RunOutput>((output) => {
const resolutionHandler = (
output: InngestTestEngine.ExecutionOutput<"function-resolved">
) => {
return {
ctx: output.ctx,
state: output.state,
result: output.result.data,
};
};

const rejectionHandler = (
output: InngestTestEngine.ExecutionOutput<"function-rejected">,
error: unknown = output.result.error
) => {
if (
typeof output === "object" &&
output !== null &&
"ctx" in output &&
"state" in output
) {
return {
ctx: output.ctx,
state: output.state,
result: output.result.data,
error,
};
})
.catch<InngestTestRun.RunOutput>((rejectedOutput) => {
if (
typeof rejectedOutput === "object" &&
rejectedOutput !== null &&
"ctx" in rejectedOutput &&
"state" in rejectedOutput
) {
return {
ctx: rejectedOutput.ctx,
state: rejectedOutput.state,
error: rejectedOutput.error,
};
}
}

throw rejectedOutput;
});
throw output;
};

if (output.result.type === "function-resolved") {
return resolutionHandler(
output as InngestTestEngine.ExecutionOutput<"function-resolved">
);
} else if (output.result.type === "function-rejected") {
return rejectionHandler(
output as InngestTestEngine.ExecutionOutput<"function-rejected">
);
} else if (output.result.type === "step-ran") {
// Any error halts execution until retries are modelled
if (
(output as InngestTestEngine.ExecutionOutput<"step-ran">).result.step
.error
) {
return rejectionHandler(
output as InngestTestEngine.ExecutionOutput<"function-rejected">,
(output as InngestTestEngine.ExecutionOutput<"step-ran">).result.step
.error
);
}
}

return output.run
.waitFor("function-resolved")
.then<InngestTestRun.RunOutput>(resolutionHandler)
.catch<InngestTestRun.RunOutput>(rejectionHandler);
}

/**
Expand Down Expand Up @@ -371,7 +403,7 @@ export class InngestTestEngine {
const steps = (options.steps || []).map((step) => {
return {
...step,
id: _internals.hashId(step.id),
id: step.idIsHashed ? step.id : _internals.hashId(step.id),
};
});

Expand Down Expand Up @@ -476,6 +508,8 @@ export class InngestTestEngine {
Promise.resolve({}) as Promise<InngestTestEngine.MockState>
);

InngestTestRun["updateState"](options, result);

const run = new InngestTestRun({
testEngine: this.clone(options),
});
Expand Down
58 changes: 39 additions & 19 deletions packages/test/src/InngestTestRun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,40 +145,28 @@ export class InngestTestRun {
return finish(exec);
}

InngestTestRun.updateState(runningState, exec.result);

const resultHandlers: Record<keyof ExecutionResults, () => void> = {
"function-resolved": () => finish(exec),
"function-rejected": () => finish(exec),
"step-not-found": () => {
processChain();
},
"step-not-found": () => processChain(),
"steps-found": () => {
// run all
const result =
exec.result as InngestTestRun.Checkpoint<"steps-found">;

if (result.steps.length > 1) {
runningState.disableImmediateExecution = true;
}

result.steps.forEach((step) => {
processChain(step.id);
});
},
"step-ran": () => {
const result = exec.result as InngestTestRun.Checkpoint<"step-ran">;

// add to our running state
runningState.steps ??= [];
runningState.steps.push({
id: result.step.name as string, // TODO we need the non-hashed ID here, or a way to map it
handler: () => {
if (result.step.error) {
throw result.step.error;
}

return result.step.data;
},
});
// if this is an error, we should stop. Later we model retries.
if (result.step.error) {
return finish(exec);
}

processChain();
},
Expand All @@ -192,4 +180,36 @@ export class InngestTestRun {

return promise;
}

/**
* Given existing state and an execution result, mutate the state.
*/
protected static updateState(
options: InngestTestEngine.InlineOptions,
checkpoint: InngestTestRun.Checkpoint<InngestTestRun.CheckpointKey>
): void {
if (checkpoint.type === "steps-found") {
const steps = (checkpoint as InngestTestRun.Checkpoint<"steps-found">)
.steps;

if (steps.length > 1) {
options.disableImmediateExecution = true;
}
} else if (checkpoint.type === "step-ran") {
const step = (checkpoint as InngestTestRun.Checkpoint<"step-ran">).step;

options.steps ??= [];
options.steps.push({
id: step.id,
idIsHashed: true,
handler: () => {
if (step.error) {
throw step.error;
}

return step.data;
},
});
}
}
}

0 comments on commit 1899d30

Please sign in to comment.