UNPKG

@inngest/test

Version:
139 lines 5.88 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.InngestTestRun = void 0; const v1_1 = require("inngest/components/execution/v1"); const promises_1 = require("inngest/helpers/promises"); const util_1 = require("./util"); /** * A test run that allows you to wait for specific checkpoints in a run that * covers many executions. * * @TODO We may need to separate run execution by {@link ExecutionVersion}. */ class InngestTestRun { constructor(options) { this.options = options; } /** * Keep executing the function until a specific checkpoint is reached. * * @TODO What if the thing we're waiting for has already happened? */ waitFor( /** * The checkpoint to wait for. */ checkpoint, /** * 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) { return __awaiter(this, void 0, void 0, function* () { let finished = false; const runningState = { events: this.options.testEngine["options"].events, steps: this.options.testEngine["options"].steps, }; const { promise, resolve, reject } = (0, promises_1.createDeferredPromise)(); const finish = (output) => { finished = true; if (output.result.type !== checkpoint) { return reject(output); } resolve(output); }; /** * Make sure we sanitize any given ID to prehash it for the user. This is * abstracted from the user entirely so they shouldn't be expected to be * providing hashes. */ const sanitizedSubset = subset && Object.assign(Object.assign(Object.assign({}, subset), ("step" in subset && typeof subset.step === "object" && subset.step !== null && "id" in subset.step && typeof subset.step.id === "string" && { step: Object.assign(Object.assign({}, subset.step), { id: v1_1._internals.hashId(subset.step.id) }), })), ("steps" in subset && Array.isArray(subset.steps) && { steps: subset.steps.map((step) => (Object.assign(Object.assign({}, step), { id: v1_1._internals.hashId(step.id) }))), })); const processChain = (targetStepId) => __awaiter(this, void 0, void 0, function* () { if (finished) { return; } const exec = yield this.options.testEngine["individualExecution"](Object.assign(Object.assign({}, runningState), { targetStepId })); if (exec.result.type === checkpoint && (!sanitizedSubset || (0, util_1.isDeeplyEqual)(sanitizedSubset, exec.result))) { return finish(exec); } InngestTestRun.updateState(runningState, exec.result); const resultHandlers = { "function-resolved": () => finish(exec), "function-rejected": () => finish(exec), "step-not-found": () => processChain(), "steps-found": () => { // run all const result = exec.result; result.steps.forEach((step) => { processChain(step.id); }); }, "step-ran": () => { const result = exec.result; // if this is an error, we should stop. Later we model retries. if (result.step.error) { return finish(exec); } processChain(); }, }; resultHandlers[exec.result.type](); }); // kick off processChain(); return promise; }); } /** * Given existing state and an execution result, mutate the state. */ static updateState(options, checkpoint) { var _a; if (checkpoint.type === "steps-found") { const steps = checkpoint .steps; if (steps.length > 1) { options.disableImmediateExecution = true; } } else if (checkpoint.type === "step-ran") { const step = checkpoint.step; (_a = options.steps) !== null && _a !== void 0 ? _a : (options.steps = []); options.steps.push({ id: step.id, idIsHashed: true, handler: () => { if (step.error) { throw step.error; } return step.data; }, }); } } } exports.InngestTestRun = InngestTestRun; //# sourceMappingURL=InngestTestRun.js.map