UNPKG

@firfi/quint-connect

Version:

Model-based testing framework connecting Quint specifications to TypeScript implementations

72 lines 3.12 kB
import { transformITFValue } from "@firfi/itf-trace-parser"; import { Effect, Schema } from "effect"; import { ItfOption } from "./schema.js"; const assumeNoSchemaRequirements = (schema) => // ItfOption preserves the action pick schema requirements, but extraction widens R. schema; export const buildEffectPicksDecoder = (picksShape) => (rawPicks) => Effect.gen(function* () { if (typeof rawPicks !== "object" || rawPicks === null) { return yield* Schema.decodeUnknown(Schema.Struct({}))(rawPicks); } const record = rawPicks; const decoded = {}; for (const [key, fieldSchema] of Object.entries(picksShape.fields)) { const schema = assumeNoSchemaRequirements(Schema.asSchema(fieldSchema)); const raw = record[key]; if (raw === undefined) { decoded[key] = yield* Schema.decodeUnknown(schema)(undefined); continue; } const value = yield* Schema.decodeUnknown(ItfOption(schema))(raw); if (value === undefined) { decoded[key] = yield* Schema.decodeUnknown(schema)(undefined); continue; } decoded[key] = value; } return decoded; }); const formatIssues = (issues) => issues.map((issue) => issue.message).join(", "); const decodeStandardPickValueSync = (rawValue, key, schema) => { const result = schema["~standard"].validate(transformITFValue(rawValue)); if (result instanceof Promise) { throw new Error("pickFrom does not support async schemas"); } if (result.issues) { throw new Error(`pickFrom "${key}" validation failed: ${formatIssues(result.issues)}`); } return result.value; }; const decodeStandardPickValue = async (rawValue, key, schema) => { const result = await schema["~standard"].validate(transformITFValue(rawValue)); if (result.issues) { throw new Error(`Pick "${key}" validation failed: ${formatIssues(result.issues)}`); } return result.value; }; export const decodeStandardPicks = async (rawPicks, picksSchema) => { const decoded = await Promise.all(Object.entries(picksSchema).map(async ([key, schema]) => [ key, await decodeStandardPickValue(rawPicks[key], key, schema) ])); return Object.fromEntries(decoded); }; const unwrapQuintOptionPick = (raw, key) => { if (raw === undefined) return undefined; if (typeof raw !== "object" || raw === null || !("tag" in raw)) { throw new Error(`pickFrom "${key}": expected Quint Option (Some/None), got: ${JSON.stringify(raw)}`); } const variant = raw; if (variant.tag === "None") return { present: false }; if (variant.tag !== "Some") { throw new Error(`pickFrom "${key}": expected Option tag "Some" or "None", got: "${variant.tag}"`); } return { present: true, value: variant.value }; }; export const pickFrom = (nondetPicks, key, schema) => { const pick = unwrapQuintOptionPick(nondetPicks.get(key), key); return pick === undefined || !pick.present ? undefined : decodeStandardPickValueSync(pick.value, key, schema); }; //# sourceMappingURL=picks.js.map