20260920173439

This commit is contained in:
oneao committed 2026-09-20 17:34:40 +08:00
1 parent f4bfc1ddfc
commit 6f03d92425
174 files changed
+23490 -157

No files matched your search

@@ -0,0 +1,91 @@
/**
* 端到端链路冒烟测试(§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)
})
})