新增: - BrandCropModal 品牌图裁剪弹窗 + cropImage 工具 - Markdown 行内短代码(inlineShortcodes + remark 插件) - MdDetails 折叠块、MdVideo 视频块组件 - directiveBlocks/inlineShortcodes 测试 其它: - 聊天后端(handler/service chat)调整 - Markdown 渲染链路、编辑器、全局样式与品牌相关面板更新
118 lines
4.1 KiB
TypeScript
118 lines
4.1 KiB
TypeScript
import assert from "node:assert/strict";
|
||
import { describe, it } from "node:test";
|
||
import {
|
||
DETAILS_DEFAULT_TITLE,
|
||
isDetailsOpen,
|
||
parseDetailsOpen,
|
||
parseVideoInput,
|
||
parseVideoLine,
|
||
splitContentSegments,
|
||
} from "./directiveBlocks.ts";
|
||
|
||
describe("parseDetailsOpen / isDetailsOpen", () => {
|
||
it("开标记整行匹配,标题缺省「点击展开」", () => {
|
||
assert.equal(isDetailsOpen("[details]"), true);
|
||
assert.equal(parseDetailsOpen("[details]"), DETAILS_DEFAULT_TITLE);
|
||
assert.equal(parseDetailsOpen("[details 点击展开看结论]"), "点击展开看结论");
|
||
assert.equal(isDetailsOpen("[details 标题] 后缀"), false);
|
||
assert.equal(isDetailsOpen("[details]"), true);
|
||
});
|
||
});
|
||
|
||
describe("parseVideoInput", () => {
|
||
it("BV 号与 B站链接", () => {
|
||
assert.deepEqual(parseVideoInput("BV1GJ411x7h7"), {
|
||
provider: "bilibili",
|
||
id: "BV1GJ411x7h7",
|
||
});
|
||
assert.deepEqual(parseVideoInput("https://www.bilibili.com/video/BV1GJ411x7h7/?p=1"), {
|
||
provider: "bilibili",
|
||
id: "BV1GJ411x7h7",
|
||
});
|
||
});
|
||
it("YouTube ID 与链接", () => {
|
||
assert.deepEqual(parseVideoInput("dQw4w9WgXcQ"), {
|
||
provider: "youtube",
|
||
id: "dQw4w9WgXcQ",
|
||
});
|
||
assert.deepEqual(parseVideoInput("https://youtu.be/dQw4w9WgXcQ"), {
|
||
provider: "youtube",
|
||
id: "dQw4w9WgXcQ",
|
||
});
|
||
assert.deepEqual(parseVideoInput("https://www.youtube.com/watch?v=dQw4w9WgXcQ"), {
|
||
provider: "youtube",
|
||
id: "dQw4w9WgXcQ",
|
||
});
|
||
});
|
||
it("非法输入返回 null", () => {
|
||
assert.equal(parseVideoInput(""), null);
|
||
assert.equal(parseVideoInput("hello world"), null);
|
||
assert.equal(parseVideoInput("https://evil.com/<script>"), null);
|
||
});
|
||
});
|
||
|
||
describe("parseVideoLine", () => {
|
||
it("整行短代码匹配且大小写不敏感", () => {
|
||
assert.deepEqual(parseVideoLine("[bilibili]BV1GJ411x7h7[/bilibili]"), {
|
||
provider: "bilibili",
|
||
id: "BV1GJ411x7h7",
|
||
});
|
||
assert.deepEqual(parseVideoLine("[BILIBILI]https://www.bilibili.com/video/BV1GJ411x7h7[/BILIBILI]"), {
|
||
provider: "bilibili",
|
||
id: "BV1GJ411x7h7",
|
||
});
|
||
assert.deepEqual(parseVideoLine("[youtube]dQw4w9WgXcQ[/youtube]"), {
|
||
provider: "youtube",
|
||
id: "dQw4w9WgXcQ",
|
||
});
|
||
});
|
||
it("标签与平台不一致或内容非法时返回 null", () => {
|
||
assert.equal(parseVideoLine("[bilibili]dQw4w9WgXcQ[/bilibili]"), null);
|
||
assert.equal(parseVideoLine("[youtube]BV1GJ411x7h7[/youtube]"), null);
|
||
assert.equal(parseVideoLine("[bilibili]随便[/bilibili]"), null);
|
||
});
|
||
});
|
||
|
||
describe("splitContentSegments: details/video", () => {
|
||
it("[details] 块拆分,正文保留 markdown", () => {
|
||
const segs = splitContentSegments(
|
||
"前文\n\n[details 结论]\n**加粗** 内容\n[/details]\n\n后文"
|
||
);
|
||
assert.deepEqual(
|
||
segs.map((s) => s.type),
|
||
["md", "details", "md"]
|
||
);
|
||
const d = segs[1];
|
||
assert.equal(d.type === "details" ? d.title : "", "结论");
|
||
assert.equal(d.type === "details" ? d.body : "", "**加粗** 内容");
|
||
});
|
||
|
||
it("details 嵌套开标签:外层按 md,内层与闭合配对(与 timeline 语义一致)", () => {
|
||
const segs = splitContentSegments("[details A]\n[details B]\n[/details]");
|
||
assert.deepEqual(segs.map((s) => s.type), ["md", "details"]);
|
||
});
|
||
|
||
it("未闭合的 details 整段按 md", () => {
|
||
const segs = splitContentSegments("正文\n\n[details A]\n没有闭合标记");
|
||
assert.deepEqual(segs.map((s) => s.type), ["md"]);
|
||
});
|
||
|
||
it("代码围栏内伪语法不拆", () => {
|
||
const segs = splitContentSegments("```\n[details 假的]\n[/details]\n```");
|
||
assert.deepEqual(segs.map((s) => s.type), ["md"]);
|
||
});
|
||
|
||
it("视频整行拆为 video 段;行内出现不拆", () => {
|
||
const segs = splitContentSegments(
|
||
"看这个:\n\n[bilibili]BV1GJ411x7h7[/bilibili]\n\n文中 [youtube]dQw4w9WgXcQ[/youtube] 不拆"
|
||
);
|
||
assert.deepEqual(
|
||
segs.map((s) => s.type),
|
||
["md", "video", "md"]
|
||
);
|
||
const v = segs[1];
|
||
assert.equal(v.type === "video" ? v.provider : "", "bilibili");
|
||
assert.equal(v.type === "video" ? v.id : "", "BV1GJ411x7h7");
|
||
});
|
||
});
|