Files
plainleaf/client/components/plainleaf_markdown_toolbar.test.ts
T
wushenghuaandCodex 645c04ed01 feat: 优化移动端笔记与编辑体验
手机端改用抽屉侧栏并移除底部导航,补充 Markdown 编辑工具栏,收拢开发者选项并改善社区扩展下载错误反馈。

Co-Authored-By: Codex <noreply@anthropic.com>
2026-08-13 06:42:18 +08:00

67 lines
1.9 KiB
TypeScript

import { EditorSelection, EditorState } from "@codemirror/state";
import type { EditorView } from "@codemirror/view";
import { expect, test } from "vitest";
import {
applyPlainleafEditorAction,
type PlainleafEditorAction,
} from "./plainleaf_markdown_toolbar.ts";
function edit(
text: string,
action: PlainleafEditorAction,
from = 0,
to = text.length,
) {
let state = EditorState.create({
doc: text,
selection: EditorSelection.range(from, to),
});
const view = {
get state() {
return state;
},
dispatch(spec: Parameters<EditorView["dispatch"]>[0]) {
state = state.update(spec).state;
},
focus() {},
} as unknown as EditorView;
expect(applyPlainleafEditorAction(view, action)).toBe(true);
return {
text: state.doc.toString(),
from: state.selection.main.from,
to: state.selection.main.to,
};
}
test("turns selected lines into headings and toggles the active heading", () => {
expect(edit("标题", "heading-1").text).toBe("# 标题");
expect(edit("# 标题", "heading-1").text).toBe("标题");
expect(edit("# 标题", "heading-2").text).toBe("## 标题");
});
test("creates Markdown lists and task items for multiple lines", () => {
expect(edit("第一项\n第二项", "bullet-list").text).toBe("- 第一项\n- 第二项");
expect(edit("第一项\n第二项", "numbered-list").text).toBe(
"1. 第一项\n2. 第二项",
);
expect(edit("第一项\n第二项", "task-list").text).toBe(
"- [ ] 第一项\n- [ ] 第二项",
);
});
test("wraps selected text and selects the editable URL", () => {
expect(edit("重点", "bold")).toMatchObject({
text: "**重点**",
from: 2,
to: 4,
});
const link = edit("官网", "link");
expect(link.text).toBe("[官网](https://)");
expect(link.text.slice(link.from, link.to)).toBe("https://");
});
test("uses fenced code for multi-line selections", () => {
expect(edit("a\nb", "code").text).toBe("```\na\nb\n```");
});