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 } from "../src/render" const __dirname = path.dirname(fileURLToPath(import.meta.url)) const DRAW_IMAGE_DIR = path.resolve(__dirname, "..") const TMP = "/tmp/draw-image-optional-integration" beforeAll(() => { if (existsSync(TMP)) rmSync(TMP, { recursive: true, force: true }) mkdirSync(TMP, { recursive: true }) }) function renderToPng(svg: string, outPath: string): void { const tmpSvg = path.join(TMP, "input.svg") writeFileSync(tmpSvg, svg) const r = spawnSync("node", [path.join(DRAW_IMAGE_DIR, "render.mjs"), tmpSvg, outPath], { encoding: "utf-8", }) if (r.status !== 0) throw new Error(`render.mjs failed: ${r.stderr || r.stdout}`) } function assertPng(filePath: string) { expect(existsSync(filePath), `PNG not found: ${filePath}`).toBe(true) const buf = readFileSync(filePath) expect(buf[0]).toBe(0x89) expect(buf[1]).toBe(0x50) expect(buf[2]).toBe(0x4e) expect(buf[3]).toBe(0x47) const width = buf.readUInt32BE(16) const height = buf.readUInt32BE(20) expect(width, `PNG width should be 1024, got ${width}`).toBe(1024) expect(height, `PNG height should be 1024, got ${height}`).toBe(1024) } describe("integration — optional subtitle and badge", () => { test("render without subtitle and without badge → valid PNG", () => { const brand = loadBrand(DRAW_IMAGE_DIR) const templateSvg = loadTemplate(DRAW_IMAGE_DIR, "cover") const args = { template: "cover", title: "Bare" } const svg = buildSvg(templateSvg, brand, args, DRAW_IMAGE_DIR) const outPath = path.join(TMP, "bare.png") renderToPng(svg, outPath) assertPng(outPath) }) test("render with subtitle and badge → valid PNG", () => { const brand = loadBrand(DRAW_IMAGE_DIR) const templateSvg = loadTemplate(DRAW_IMAGE_DIR, "cover") const args = { template: "cover", title: "Full", subtitle: "Sub Text", slots: { badge: "mic" }, } const svg = buildSvg(templateSvg, brand, args, DRAW_IMAGE_DIR) const outPath = path.join(TMP, "full.png") renderToPng(svg, outPath) assertPng(outPath) }) })