@firfi/quint-connect
Version:
Model-based testing framework connecting Quint specifications to TypeScript implementations
78 lines • 3 kB
JavaScript
import { Cause, Effect, Exit, Option, Schema } from "effect";
import { transformITFValue } from "@firfi/itf-trace-parser";
import { decodeStandardPicks } from "./itf/picks.js";
import { quintRun } from "./runner/runner.js";
export { defaultConfig } from "./driver/types.js";
export { QuintError, QuintNotFoundError } from "./cli/quint.js";
export { NoTracesError, StateMismatchError, TraceReplayError } from "./runner/runner.js";
export const stateCheck = (deserializeState, compareState) => ({ compareState, deserializeState });
// Implementation
export function defineDriver(schema, factory
// eslint-disable-next-line @typescript-eslint/no-explicit-any
) {
return () => {
const result = factory();
const actions = {};
for (const name of Object.keys(schema)) {
actions[name] = { picks: schema[name], handler: result[name] };
}
return {
actions,
...(result.getState ? { getState: result.getState } : {}),
...(result.config ? { config: result.config } : {})
};
};
}
const wrapAction = (actionDef) => {
const fields = {};
for (const key of Object.keys(actionDef.picks)) {
fields[key] = Schema.Unknown;
}
return {
picks: Schema.Struct(fields),
handler: (rawPicks) => Effect.promise(async () => {
const decoded = await decodeStandardPicks(rawPicks, actionDef.picks);
await Promise.resolve(actionDef.handler(decoded));
})
};
};
const wrapDriver = (simple) => {
const actions = {};
for (const [action, def] of Object.entries(simple.actions)) {
actions[action] = wrapAction(def);
}
const simpleGetState = simple.getState;
return {
actions,
...(simpleGetState !== undefined ? { getState: () => Effect.sync(simpleGetState) } : {}),
...(simple.config !== undefined ? { config: simple.config } : {})
};
};
export const run = (opts) => {
const { driver, stateCheck: sc, ...runOpts } = opts;
const program = quintRun({
...runOpts,
driverFactory: {
create: () => Effect.promise(async () => wrapDriver(await Promise.resolve(driver())))
},
stateCheck: sc !== undefined
? {
compareState: sc.compareState,
deserializeState: (raw) => Effect.sync(() => sc.deserializeState(transformITFValue(raw)))
}
: undefined
});
return Effect.runPromiseExit(program).then((exit) => {
if (Exit.isSuccess(exit))
return exit.value;
const failure = Cause.failureOption(exit.cause);
if (Option.isSome(failure))
throw failure.value;
const defect = Cause.dieOption(exit.cause);
if (Option.isSome(defect))
throw defect.value;
throw new Error("Unknown error in quint-connect run()");
});
};
export { transformITFValue } from "@firfi/itf-trace-parser";
//# sourceMappingURL=simple.js.map