* 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>
36 lines
No EOL
1.4 KiB
TypeScript
36 lines
No EOL
1.4 KiB
TypeScript
import { describe, test, expect, beforeAll } from "vitest"
|
|
import { existsSync, rmSync, mkdirSync, writeFileSync, copyFileSync, readFileSync } from "node:fs"
|
|
import path from "node:path"
|
|
import { fileURLToPath } from "node:url"
|
|
import { spawnSync } from "node:child_process"
|
|
import { validateBrand } from "../src/config"
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
const DRAW_IMAGE_DIR = path.resolve(__dirname, "..")
|
|
const TMP = "/tmp/draw-image-bad-input"
|
|
|
|
beforeAll(() => {
|
|
if (existsSync(TMP)) rmSync(TMP, { recursive: true, force: true })
|
|
mkdirSync(TMP, { recursive: true })
|
|
})
|
|
|
|
describe("e2e — bad input (unit-level, no file mutation)", () => {
|
|
test("invalid brand.json rejected by validateBrand", () => {
|
|
expect(() => validateBrand({ base: "#0a0a0a", surface: "#121212", fg: "#ededed", muted: "#a1a1aa" }))
|
|
.toThrow(/accent/)
|
|
})
|
|
|
|
test("non-hex accent rejected", () => {
|
|
expect(() => validateBrand({ base: "#0a0a0a", surface: "#121212", fg: "#ededed", muted: "#a1a1aa", accent: "green" }))
|
|
.toThrow(/hex/)
|
|
})
|
|
|
|
test("cli exits non-zero with missing template file", () => {
|
|
const out = path.join(TMP, "bad.png")
|
|
const r = spawnSync("node", ["--experimental-strip-types", path.join(DRAW_IMAGE_DIR, "cli.ts"), "render", "nonexistent", "--title", "Bad", "--out", out], {
|
|
encoding: "utf-8",
|
|
cwd: DRAW_IMAGE_DIR,
|
|
})
|
|
expect(r.status).not.toBe(0)
|
|
})
|
|
}) |