- 新增可复用的 markdown-echarts 工作区,支持安全的 YAML 围栏、默认值、语义校验、错误占位和 SVG 渲染 - 将 ECharts 接入统一 Markdown、快速预览、精确预览与 PDF 链路,并复用 Mermaid 的不可跨页和超高图单页适配策略 - 默认示例加入 ECharts,增加源文本折叠、顶部文档状态、页码输入跳转与滚动同步 - 快速预览改用外层容器滚动,使滚动条与精确预览统一贴在预览区域右侧,并兼容显示缩放 - 完善 Docker 工作区复制、可配置 Compose 镜像、测试覆盖和进度文档
82 lines
1.9 KiB
TypeScript
82 lines
1.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
normalizeAndValidateEChartsOption
|
|
} from "../src/index.js";
|
|
|
|
describe("normalizeAndValidateEChartsOption", () => {
|
|
it("接受首版系列和内置数据转换", () => {
|
|
const normalized = normalizeAndValidateEChartsOption({
|
|
dataset: {
|
|
source: [
|
|
["name", "value"],
|
|
["A", 1]
|
|
],
|
|
transform: {
|
|
type: "sort",
|
|
config: {
|
|
dimension: "value",
|
|
order: "desc"
|
|
}
|
|
}
|
|
},
|
|
series: [
|
|
{
|
|
type: "bar",
|
|
encode: {
|
|
x: "name",
|
|
y: "value"
|
|
}
|
|
}
|
|
]
|
|
});
|
|
|
|
expect(normalized).toMatchObject({
|
|
series: [{ type: "bar" }]
|
|
});
|
|
expect(Object.getPrototypeOf(normalized)).toBe(
|
|
Object.prototype
|
|
);
|
|
expect(normalized.hasOwnProperty("series")).toBe(true);
|
|
});
|
|
|
|
it("拒绝不支持的系列", () => {
|
|
expect(() =>
|
|
normalizeAndValidateEChartsOption({
|
|
series: [{ type: "custom" }]
|
|
})
|
|
).toThrow(/暂不支持 custom/u);
|
|
});
|
|
|
|
it("拒绝外部资源和危险链接", () => {
|
|
expect(() =>
|
|
normalizeAndValidateEChartsOption({
|
|
title: {
|
|
text: "示例",
|
|
subtext: "https://example.com/chart"
|
|
},
|
|
series: [{ type: "line" }]
|
|
})
|
|
).toThrow(/危险 URL/u);
|
|
});
|
|
|
|
it("拒绝 HTML formatter", () => {
|
|
expect(() =>
|
|
normalizeAndValidateEChartsOption({
|
|
tooltip: {
|
|
formatter: "<img src=x onerror=alert(1)>"
|
|
},
|
|
series: [{ type: "line" }]
|
|
})
|
|
).toThrow(/不含 HTML/u);
|
|
});
|
|
|
|
it("拒绝原型污染属性", () => {
|
|
const option = JSON.parse(
|
|
'{"series":[{"type":"line"}],"__proto__":{"polluted":true}}'
|
|
);
|
|
expect(() => normalizeAndValidateEChartsOption(option)).toThrow(
|
|
/禁止属性/u
|
|
);
|
|
});
|
|
});
|