postprocess.test.ts 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import { test } from "node:test";
  2. import assert from "node:assert/strict";
  3. import {
  4. applyLengthLimits,
  5. isMissingGithubScenes,
  6. } from "../src/postprocess.ts";
  7. // --- applyLengthLimits: scene id repair ---
  8. test("applyLengthLimits fills missing scene id deterministically", () => {
  9. const input = { scenes: [{ narration: "a" }, { id: "", narration: "b" }] };
  10. const out = applyLengthLimits(input, "news") as any;
  11. assert.equal(out.scenes[0].id, "scene-1");
  12. assert.equal(out.scenes[1].id, "scene-2");
  13. });
  14. test("applyLengthLimits keeps existing scene ids untouched", () => {
  15. const input = { scenes: [{ id: "my-scene", narration: "a" }] };
  16. const out = applyLengthLimits(input, "news") as any;
  17. assert.equal(out.scenes[0].id, "my-scene");
  18. });
  19. // --- isMissingGithubScenes: github board structure detection ---
  20. // Regression guard: the detection used to be an object flag that
  21. // applyLengthLimits deleted before the caller could read it (dead retry path).
  22. test("isMissingGithubScenes: true when no scene carries a github object", () => {
  23. const input = {
  24. scenes: [
  25. { id: "s1", title: "overview", narration: "..." },
  26. { id: "s2", title: "another overview", narration: "..." },
  27. ],
  28. };
  29. assert.equal(isMissingGithubScenes(applyLengthLimits(input, "github-trending")), true);
  30. });
  31. test("isMissingGithubScenes: false when at least one scene has github block", () => {
  32. const input = {
  33. scenes: [
  34. { id: "s1", narration: "...", github: { repo: {}, highlights: "x", intro: "y", review: "z" } },
  35. { id: "s2", narration: "..." },
  36. ],
  37. };
  38. assert.equal(isMissingGithubScenes(applyLengthLimits(input, "github-trending")), false);
  39. });
  40. test("isMissingGithubScenes: true for non-object / missing scenes input", () => {
  41. assert.equal(isMissingGithubScenes(undefined), true);
  42. assert.equal(isMissingGithubScenes({}), true);
  43. assert.equal(isMissingGithubScenes({ scenes: [] }), true);
  44. });
  45. test("isMissingGithubScenes ignores non-github templates' shape via caller", () => {
  46. // Detection itself is template-agnostic; the generate layer gates it on
  47. // github-trending/github-weekly only. Here we just pin the pure behavior.
  48. const input = { scenes: [{ narration: "plain news scene" }] };
  49. assert.equal(isMissingGithubScenes(input), true);
  50. });
  51. // --- applyLengthLimits must not leak internal markers into output ---
  52. test("applyLengthLimits output contains no internal marker keys", () => {
  53. const input = {
  54. scenes: [{ narration: "overview only, no github blocks here" }],
  55. };
  56. const out = applyLengthLimits(input, "github-weekly") as any;
  57. assert.equal(Object.hasOwn(out, "__missingGithubScenes"), false);
  58. });