Files
workspace/code/one-designer/packages/report-designer/tests/smoke.test.ts
T
2026-09-20 17:34:40 +08:00

92 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 端到端链路冒烟测试(§17 V1 验收标准)。
*
* 验证完整链路:
* ReportDocument(core)
* → 数据注入 + 布局(layout,含分组/聚合)
* → LayoutDocument
* → HTML/SVG Renderer(renderer)
* → Designer 编辑(designer)
*/
import { describe, expect, it } from "vitest"
import { createDocument, createTableElement } from "@report/core"
import { createEstimateMeasurer, createPassthroughFontResolver, layoutDocument } from "@report/layout"
import { renderHtml, renderSvg, createPdfRenderer } from "@report/renderer"
import { EditorSession, createTextElement } from "@report/designer"
const measurer = createEstimateMeasurer()
const fontResolver = createPassthroughFontResolver()
describe("端到端冒烟(§17)", () => {
it("完整链路:建文档 → 布局 → HTML/SVG → Designer 编辑", async () => {
// 1. Core:创建文档 + 明细表
const doc = createDocument({ name: "销售单" })
doc.datasets = { sales: { id: "sales" } }
const detail = doc.sections.find((s) => s.kind === "detail")!
detail.children.push(
createTableElement("tbl", { x: 0, y: 0, width: 180, height: 20 }, "sales", [
{ id: "c1", width: 90, header: "商品", binding: { field: "name" } },
{ id: "c2", width: 90, header: "金额", binding: { field: "amount" }, align: "right" },
]),
)
const header = doc.sections.find((s) => s.kind === "page-header")!
header.children.push({
id: "title",
type: "text",
frame: { x: 0, y: 0, width: 100, height: 8 },
props: { text: "销售单" },
})
const rows = [
{ name: "苹果", amount: 100 },
{ name: "香蕉", amount: 200 },
{ name: "橙子", amount: 300 },
]
// 2. Layout:数据注入 + 布局
const layout = await layoutDocument(
doc,
{ data: { sales: rows }, parameters: { } },
{ textMeasurer: measurer, fontResolver },
)
expect(layout.pageCount).toBeGreaterThanOrEqual(1)
expect(layout.diagnostics.filter((d) => d.severity === "error")).toHaveLength(0)
// 3. Renderer:HTML + SVG 渲染,页数一致
const html = renderHtml(layout)
const svg = renderSvg(layout)
expect(html.pageCount).toBe(layout.pageCount)
expect(svg.pageCount).toBe(layout.pageCount)
expect(html.content).toContain("销售单")
expect(html.content).toContain("苹果")
expect(svg.content).toContain("苹果")
// PDF 缺后端 → 诊断而非抛异常
const pdf = createPdfRenderer().render(layout)
expect(pdf.target).toBe("pdf")
expect(pdf.diagnostics.length).toBeGreaterThan(0)
// 4. Designer:编辑(移动 + 撤销)
const editor = new EditorSession(doc)
editor.select("title")
const before = editor.getDocument().sections
.find((s) => s.kind === "page-header")!.children[0]!.frame
editor.moveElements({ title: { x: 20, y: 0, width: 100, height: 8 } })
const afterMove = editor.getDocument().sections
.find((s) => s.kind === "page-header")!.children[0]!.frame
expect(afterMove.x).toBe(20)
editor.undo()
const afterUndo = editor.getDocument().sections
.find((s) => s.kind === "page-header")!.children[0]!.frame
expect(afterUndo.x).toBe(before.x)
// 新增元素
const beforeCount = editor.getDocument().sections
.find((s) => s.kind === "detail")!.children.length
editor.addElement(detail.id, createTextElement({ x: 0, y: 0, width: 30, height: 8 }, "备注"))
const afterAdd = editor.getDocument().sections
.find((s) => s.kind === "detail")!.children.length
expect(afterAdd).toBe(beforeCount + 1)
})
})