opencode-config/.opencode/draw-image/tests/idempotency.test.ts
Sergey 56b67d2d5c
feat(draw-image): SVG template renderer for on-brand covers (#134)
* feat(draw-image): add SVG template render engine

* feat(draw-image): add opencode plugin and tool tests

* test(draw-image): add vitest unit integration e2e suite

* chore(draw-image): wire CI dependabot docs and ADR

* docs(handoff): set PR number

* docs(handoff): fix PR number placeholder in frontmatter

* fix(ci): use tempfile and trailing newline in draw-image tests

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-07-29 23:42:50 +03:00

51 lines
No EOL
2 KiB
TypeScript

import { describe, test, expect, beforeAll } from "vitest"
import { existsSync, readFileSync, rmSync, mkdirSync, writeFileSync } from "node:fs"
import path from "node:path"
import { fileURLToPath } from "node:url"
import { spawnSync } from "node:child_process"
import { loadBrand } from "../src/config"
import { loadTemplate, buildSvg, computeHash } from "../src/render"
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const DRAW_IMAGE_DIR = path.resolve(__dirname, "..")
const TMP = "/tmp/draw-image-idempotency"
beforeAll(() => {
if (existsSync(TMP)) rmSync(TMP, { recursive: true, force: true })
mkdirSync(TMP, { recursive: true })
})
function renderCli(template: string, title: string, out: string, slots?: string): { status: number; stdout: string; stderr: string } {
const args = ["--experimental-strip-types", path.join(DRAW_IMAGE_DIR, "cli.ts"), "render", template, "--title", title, "--out", out]
if (slots) args.push("--slots", slots)
return spawnSync("node", args, { encoding: "utf-8", cwd: DRAW_IMAGE_DIR })
}
describe("integration — idempotency", () => {
test("re-render with same args skips", () => {
const out = path.join(TMP, "cover.png")
const r1 = renderCli("cover", "Same Title", out)
expect(r1.status).toBe(0)
const result1 = JSON.parse(r1.stdout)
expect(result1.status).toBe("rendered")
const r2 = renderCli("cover", "Same Title", out)
expect(r2.status).toBe(0)
const result2 = JSON.parse(r2.stdout)
expect(result2.status).toBe("skipped")
})
test("changed title re-renders", () => {
const out = path.join(TMP, "cover2.png")
const r1 = renderCli("cover", "Title A", out)
const result1 = JSON.parse(r1.stdout)
expect(result1.status).toBe("rendered")
const r2 = renderCli("cover", "Title B", out)
const result2 = JSON.parse(r2.stdout)
expect(result2.status).toBe("rendered")
const meta = JSON.parse(readFileSync(out.replace(/\.png$/, ".meta.json"), "utf-8"))
expect(meta.hash).toHaveLength(64)
})
})