import { afterEach, describe, expect, it } from "bun:test"; import { execFile } from "node:child_process"; import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; import { promisify } from "node:util"; const execFileAsync = promisify(execFile); const createdPaths: string[] = []; afterEach(async () => { await Promise.all( createdPaths.splice(0).map((path) => rm(path, { force: true, recursive: true })), ); }); describe("service area workflow script", () => { it("writes the wrapped render payload required by store_render_ref", async () => { const directory = await mkdtemp(join(tmpdir(), "service-area-script-")); createdPaths.push(directory); const time = "2026-04-01T08:00:00+08:00"; const inputs = { pipes: { data: [{ id: "P1", node1: "R1", node2: "N1" }] }, reservoirs: { data: [{ id: "R1" }] }, links: { data: [{ id: "P1", flow: 1, time }] }, nodes: { data: [ { id: "R1", pressure: 30, actual_demand: 0, time }, { id: "N1", pressure: 28, actual_demand: 2, time }, ], }, }; const paths = Object.fromEntries( await Promise.all( Object.entries(inputs).map(async ([name, value]) => { const path = join(directory, `${name}.json`); await writeFile(path, JSON.stringify(value)); return [name, path] as const; }), ), ); const outputPath = join(directory, "service-area-wrapper.json"); await execFileAsync( "python3", [ resolve( ".opencode/skills/workflow/service-area-analysis/scripts/service_area_partition.py", ), "--pipe-props", paths.pipes!, "--reservoirs", paths.reservoirs!, "--links", paths.links!, "--nodes", paths.nodes!, "--target-time", time, "--output", outputPath, ], { cwd: directory }, ); const wrapper = JSON.parse(await readFile(outputPath, "utf8")) as { data: { node_area_map: Record }; location: { file_path: string }; metadata: { schema_version: number }; }; expect(wrapper.location.file_path).toBe(outputPath); expect(wrapper.metadata.schema_version).toBe(1); expect(wrapper.data.node_area_map).toMatchObject({ R1: "R1", N1: "R1" }); }); });