test/turn.test.js
Rama main · réplica de lectura del repositorio original.
import { test } from "node:test";
import assert from "node:assert/strict";
import { runTurn } from "../src/ai/turn.js";
const deck = {
title: "t",
sections: ["Intro"],
slides: [{ type: "bullets", section: 0, presenter: "P", headline: "Points", bullets: ["a", "b", "c", "d"] }],
};
test("runTurn drops a stray op missing the `op` field and still applies the valid ones", async () => {
const chat = async () => ({
data: {
ops: [
{ index: 0, patch: { headline: "should be ignored" } }, // malformed — no op
{ op: "update_slide", index: 0, patch: { headline: "Rewritten", bullets: ["a", "b", "c", "d"] } },
],
},
});
const r = await runTurn({ deck, instruction: "rewrite slide 1", model: "mock", chat });
assert.equal(r.ok, true);
assert.equal(r.deck.slides[0].headline, "Rewritten", "the valid op applied despite the stray item");
assert.equal(r.deck.slides[0].bullets.length, 4);
});
test("runTurn reports all-malformed ops and repairs before giving up", async () => {
// First call returns ops with no `op` field at all; the repair call returns a
// valid rewrite.
let calls = 0;
const chat = async () => {
calls++;
if (calls === 1) return { data: { ops: [{ index: 0, patch: { headline: "x" } }, {}] } };
return { data: { ops: [{ op: "update_slide", index: 0, patch: { headline: "Fixed", bullets: ["a", "b", "c", "d"] } }] } };
};
const r = await runTurn({ deck, instruction: "rewrite slide 1", model: "mock", chat });
assert.equal(r.ok, true, "the repair pass recovered it");
assert.equal(r.deck.slides[0].headline, "Fixed");
assert.ok(calls >= 2, "the malformed response was fed back, not just failed");
});
test("runTurn keeps the deck untouched when a repair never produces a valid op", async () => {
const chat = async () => ({ data: { ops: [{ index: 0 }, {}] } });
const r = await runTurn({ deck, instruction: "rewrite slide 1", model: "mock", chat });
assert.equal(r.ok, false);
assert.deepEqual(r.deck, deck, "the deck is unchanged on total failure");
assert.ok(r.errors.some((e) => e.includes("malformed") || e.includes("op")), "the error names the malformed ops");
});