Something went wrong. Try again.
A functional toolkit for authoring resource-leveling algorithms — compose constraint and scoring blocks, enumerate feasible schedules
Something went wrong. Try again.
4.5 kB · 127 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128// Run provenance: every materialized project is self-describing — filled// config, engine version, achieved scores — and survives a JSON round trip.
import { describe, expect, test } from "bun:test";
import { JsonReader } from "../../src/json/JsonReader.ts";import { JsonWriter } from "../../src/json/JsonWriter.ts";import { runFromConfig } from "../../src/level-blocks/runConfig.ts";import { STANDARD_CODES } from "../../src/level-blocks/standard.ts";import { LEVELSET_VERSION } from "../../src/version.ts";
import { MON_JAN_5, SAT_JAN_10, makeAssignment, makeProject, makeResource, makeTask,} from "../level-core/fixtures.ts";
function project() { const t1 = makeTask({ uniqueId: 1, start: MON_JAN_5, finish: SAT_JAN_10 }); const t2 = makeTask({ uniqueId: 2, start: MON_JAN_5, finish: SAT_JAN_10 }); return makeProject([t1, t2], { resources: [makeResource(100, "Crew")], assignments: [makeAssignment(1, 100), makeAssignment(2, 100)], });}
function config() { return { formatVersion: 1, seed: 42, pipeline: { formatVersion: 1, blocks: [ { instanceId: "crew-cap", code: STANDARD_CODES.maxConcurrentResource, params: { resourceUniqueId: 100, max: 1 }, }, { instanceId: "makespan", code: STANDARD_CODES.makespan, params: {} }, { instanceId: "search", code: STANDARD_CODES.serialSGS, params: {} }, ], }, };}
describe("run provenance", () => { test("materialize embeds version, filled config, seed, and scores", async () => { const run = runFromConfig(project(), config()); const best = (await run.best())!; const leveled = run.materialize(best);
const provenance = leveled.levelset!; expect(provenance.levelsetVersion).toBe(LEVELSET_VERSION); expect(provenance.search).toBe("serial-SGS"); expect(provenance.seed).toBe(42); expect(provenance.scores).toEqual({ makespan: best.makespan }); expect(provenance.generatedAt).toMatch(/^\d{4}-\d{2}-\d{2}T/); // The embedded config is the FILLED one — rerunning it reproduces the run. expect(provenance.runConfig).toEqual(run.config as never); const rerun = runFromConfig(project(), provenance.runConfig); const rebest = (await rerun.best())!; expect(rebest.tasks).toEqual(best.tasks); });
test("provenance survives a JSON write → read round trip", async () => { const run = runFromConfig(project(), config()); const leveled = run.materialize((await run.best())!);
const json = new JsonWriter().write(leveled); const reread = new JsonReader().read(json); expect(reread.levelset).toEqual(leveled.levelset); });
test("unknown provenance keys survive the round trip (forward compatibility)", async () => { // A levelset block written by a newer version (or annotated app-side) // must not be silently truncated to this version's fields on re-save. const run = runFromConfig(project(), config()); const leveled = run.materialize((await run.best())!); const annotated = { ...leveled, levelset: { ...leveled.levelset!, futureField: { nested: true } }, };
const reread = new JsonReader().read(new JsonWriter().write(annotated)); expect(reread.levelset).toEqual(annotated.levelset); expect((reread.levelset as Record<string, unknown>)["futureField"]).toEqual( { nested: true }, ); });
test("unknown nested sweep provenance keys survive the round trip", async () => { const run = runFromConfig(project(), config()); const leveled = run.materialize((await run.best())!); const annotated = { ...leveled, levelset: { ...leveled.levelset!, sweep: { combinations: 2, feasibleCells: 1, winner: { cap: 2 }, skipped: [], futureDiagnostic: { retained: true }, }, }, };
const reread = new JsonReader().read(new JsonWriter().write(annotated)); expect( (reread.levelset!.sweep as Record<string, unknown>)["futureDiagnostic"], ).toEqual({ retained: true, }); });
test("plain projects have no levelset block and reads tolerate garbage", () => { const json = new JsonWriter().write(project()); const reread = new JsonReader().read(json); expect(reread.levelset).toBeUndefined();
const garbage = new JsonReader().read('{"levelset": {"nonsense": true}}'); expect(garbage.levelset).toBeUndefined(); });});