diff --git a/packages/mini-markdown-editor/src/components/providers/__test__/config-provider.test.tsx b/packages/mini-markdown-editor/src/components/providers/__test__/config-provider.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..39a4242cc66a3aaae9d82a150503474b413a49b6
--- /dev/null
+++ b/packages/mini-markdown-editor/src/components/providers/__test__/config-provider.test.tsx
@@ -0,0 +1,87 @@
+import { render, screen } from "@testing-library/react";
+import { describe, test, expect } from "vitest";
+import { ConfigContext, ConfigProvider } from "../config-provider";
+import { defaultGlobalConfig } from "@/config/global";
+import type { GlobalConfig } from "@/types/global-config";
+import { useContext } from "react";
+
+// 测试用消费者组件
+const ConfigConsumer = () => {
+ const config = useContext(ConfigContext);
+ return (
+
+ {config.theme}
+ {config.locale}
+
+ );
+};
+
+describe("ConfigProvider Provider测试", () => {
+ // 测试默认配置
+ test("应提供默认配置", () => {
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByTestId("theme")).toHaveTextContent(defaultGlobalConfig.theme!);
+ expect(screen.getByTestId("locale")).toHaveTextContent(defaultGlobalConfig.locale!);
+ });
+
+ // 测试自定义配置合并
+ test("应合并自定义配置", () => {
+ const customConfig: GlobalConfig = {
+ theme: "dark",
+ };
+
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByTestId("theme")).toHaveTextContent("dark");
+ expect(screen.getByTestId("locale")).toHaveTextContent(defaultGlobalConfig.locale!);
+ });
+
+ // 测试空配置处理
+ test("应处理空配置", () => {
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByTestId("theme")).toHaveTextContent(defaultGlobalConfig.theme!);
+ expect(screen.getByTestId("locale")).toHaveTextContent(defaultGlobalConfig.locale!);
+ });
+
+ // 测试深层属性覆盖
+ test("应深度合并配置", () => {
+ const customConfig = {
+ toolbars: {
+ addTools: [],
+ excludeTools: [],
+ },
+ } as GlobalConfig;
+
+ const TestComponent = () => {
+ const config = useContext(ConfigContext);
+ return {JSON.stringify(config.toolbars)};
+ };
+
+ render(
+
+
+ ,
+ );
+
+ const expected = {
+ ...defaultGlobalConfig.toolbars,
+ ...customConfig.toolbars,
+ };
+
+ expect(screen.getByTestId("editor")).toHaveTextContent(JSON.stringify(expected));
+ });
+});
diff --git a/packages/mini-markdown-editor/src/components/providers/__test__/toolbar-provider.test.tsx b/packages/mini-markdown-editor/src/components/providers/__test__/toolbar-provider.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..ba80eb23df75181960a3ebfa714e6fbebeffa2db
--- /dev/null
+++ b/packages/mini-markdown-editor/src/components/providers/__test__/toolbar-provider.test.tsx
@@ -0,0 +1,142 @@
+import { render, screen } from "@testing-library/react";
+import { describe, test, expect, vi, beforeEach } from "vitest";
+import { ToolbarProvider, ToolbarContext } from "../toolbar-provider";
+import { toolbarConfig as toolbarManager } from "@/config/toolbar";
+import { useContext } from "react";
+
+// 模拟工具栏配置模块
+vi.mock("@/config/toolbar", () => ({
+ toolbarConfig: {
+ getDefaultToolbar: vi.fn(() => [
+ { type: "bold", title: "加粗" },
+ { type: "italic", title: "斜体" },
+ ]),
+ updateToolbars: vi.fn(),
+ },
+}));
+
+// 测试消费者组件
+const TestConsumer = () => {
+ const context = useContext(ToolbarContext);
+ return (
+
+ {context?.toolbars.map((item) => (
+
+ {item.title}
+
+ ))}
+
+ );
+};
+
+describe("ToolbarProvider Provider测试", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ // 基础功能测试
+ test("应渲染默认工具栏", () => {
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByTestId("bold")).toBeInTheDocument();
+ expect(screen.getByTestId("italic")).toBeInTheDocument();
+ expect(toolbarManager.updateToolbars).toHaveBeenCalledWith([
+ expect.objectContaining({ type: "bold" }),
+ expect.objectContaining({ type: "italic" }),
+ ]);
+ });
+
+ // 添加工具测试
+ test("应合并新增工具", () => {
+ const customConfig = {
+ addTools: [{ type: "underline", title: "下划线" }],
+ };
+
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByTestId("bold")).toBeInTheDocument();
+ expect(screen.getByTestId("italic")).toBeInTheDocument();
+ expect(screen.getByTestId("underline")).toBeInTheDocument();
+ });
+
+ // 排除工具测试
+ test("应过滤排除的工具", () => {
+ const customConfig = {
+ excludeTools: ["italic"],
+ };
+
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByTestId("bold")).toBeInTheDocument();
+ expect(screen.queryByTestId("italic")).toBeNull();
+ });
+
+ // 排序工具测试
+ test("应按指定顺序排序工具", () => {
+ const customConfig = {
+ orderTools: [{ type: "italic", order: 1 }],
+ };
+
+ const { container } = render(
+
+
+ ,
+ );
+
+ const items = container.querySelectorAll("[data-testid]");
+ expect(items[0].getAttribute("data-testid")).toBe("italic");
+ expect(items[1].getAttribute("data-testid")).toBe("bold");
+ });
+
+ // 组合功能测试
+ test("应同时处理添加、排除和排序", () => {
+ const customConfig = {
+ addTools: [{ type: "underline", title: "下划线" }],
+ excludeTools: ["bold"],
+ orderTools: [{ type: "underline", order: 0 }],
+ };
+
+ render(
+
+
+ ,
+ );
+
+ const items = screen.getAllByTestId(/.*/);
+ expect(items).toHaveLength(2);
+ expect(items[0]).toHaveAttribute("data-testid", "underline");
+ expect(items[1]).toHaveAttribute("data-testid", "italic");
+ });
+
+ // 配置更新测试
+ test("配置变化时应更新工具栏", async () => {
+ const { rerender } = render(
+
+
+ ,
+ );
+
+ expect(screen.queryByTestId("bold")).toBeNull();
+
+ rerender(
+
+
+ ,
+ );
+
+ expect(screen.getByTestId("bold")).toBeInTheDocument();
+ expect(screen.queryByTestId("italic")).toBeNull();
+ });
+});
diff --git a/packages/mini-markdown-editor/src/store/__test__/editor.test.ts b/packages/mini-markdown-editor/src/store/__test__/editor.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9132f25ccac41d42bf2e4d0d27095801e4028163
--- /dev/null
+++ b/packages/mini-markdown-editor/src/store/__test__/editor.test.ts
@@ -0,0 +1,76 @@
+import { describe, test, expect, vi } from "vitest";
+import { useEditorContentStore } from "../editor";
+import type { EditorView } from "@codemirror/view";
+
+// 模拟 EditorView 和 HTMLElement
+const mockEditorView = { destroy: vi.fn() } as unknown as EditorView;
+const mockPreviewElement = document.createElement("div");
+
+describe("useEditorContentStore Store测试", () => {
+ // 创建独立的 store 实例用于测试
+ const useTestStore = useEditorContentStore;
+
+ test("初始状态应为空值", () => {
+ const state = useTestStore.getState();
+
+ expect(state.content).toBe("");
+ expect(state.scrollWrapper).toBe("");
+ expect(state.editorView).toBeNull();
+ expect(state.previewView).toBeNull();
+ });
+
+ test("应正确更新内容", () => {
+ // 测试普通字符串
+ useTestStore.getState().setContent("Hello World");
+ expect(useTestStore.getState().content).toBe("Hello World");
+
+ // 测试特殊字符
+ useTestStore.getState().setContent("HTML
");
+ expect(useTestStore.getState().content).toBe("HTML
");
+ });
+
+ test("应正确设置滚动容器标识", () => {
+ useTestStore.getState().setScrollWrapper("#editor");
+ expect(useTestStore.getState().scrollWrapper).toBe("#editor");
+
+ useTestStore.getState().setScrollWrapper("");
+ expect(useTestStore.getState().scrollWrapper).toBe("");
+ });
+
+ test("应正确处理编辑器视图", () => {
+ // 设置编辑器视图
+ useTestStore.getState().setEditorView(mockEditorView);
+ expect(useTestStore.getState().editorView).toBe(mockEditorView);
+
+ // 清除编辑器视图
+ useTestStore.getState().setEditorView(null);
+ expect(useTestStore.getState().editorView).toBeNull();
+ });
+
+ test("应正确处理预览视图", () => {
+ // 设置预览元素
+ useTestStore.getState().setPreviewView(mockPreviewElement);
+ expect(useTestStore.getState().previewView).toBe(mockPreviewElement);
+
+ // 清除预览元素
+ useTestStore.getState().setPreviewView(null);
+ expect(useTestStore.getState().previewView).toBeNull();
+ });
+
+ test("应支持多次连续更新", () => {
+ // 连续更新内容
+ useTestStore.getState().setContent("First");
+ useTestStore.getState().setContent("Second");
+ expect(useTestStore.getState().content).toBe("Second");
+
+ // 混合更新不同类型状态
+ useTestStore.getState().setScrollWrapper("wrapper");
+ useTestStore.getState().setPreviewView(mockPreviewElement);
+ useTestStore.getState().setEditorView(mockEditorView);
+
+ const finalState = useTestStore.getState();
+ expect(finalState.scrollWrapper).toBe("wrapper");
+ expect(finalState.previewView).toBe(mockPreviewElement);
+ expect(finalState.editorView).toBe(mockEditorView);
+ });
+});
diff --git a/packages/mini-markdown-editor/src/store/__test__/toolbar.test.tsx b/packages/mini-markdown-editor/src/store/__test__/toolbar.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..b5dbfe79d0c0cee35cd55a000e57b3cafd63b325
--- /dev/null
+++ b/packages/mini-markdown-editor/src/store/__test__/toolbar.test.tsx
@@ -0,0 +1,120 @@
+import { describe, test, expect } from "vitest";
+import { useToolbarStore } from "../toolbar";
+
+// 创建独立的 store 实例用于测试
+const useTestStore = useToolbarStore;
+
+// 模拟 React 组件
+const MockComponent = Sidebar
;
+
+describe("useToolbarStore Store测试", () => {
+ // 每次测试前重置状态
+ beforeEach(() => {
+ useTestStore.setState({
+ isFullScreen: false,
+ isOnlyWrite: false,
+ isOnlyPreview: false,
+ isSidebar: false,
+ sidebarComponent: null,
+ componentMark: null,
+ });
+ });
+
+ test("初始状态应为默认值", () => {
+ const state = useTestStore.getState();
+
+ expect(state.isFullScreen).toBe(false);
+ expect(state.isOnlyWrite).toBe(false);
+ expect(state.isOnlyPreview).toBe(false);
+ expect(state.isSidebar).toBe(false);
+ expect(state.sidebarComponent).toBeNull();
+ expect(state.componentMark).toBeNull();
+ });
+
+ describe("全屏状态", () => {
+ test("应正确切换全屏状态", () => {
+ useTestStore.getState().setIsFullScreen(true);
+ expect(useTestStore.getState().isFullScreen).toBe(true);
+
+ useTestStore.getState().setIsFullScreen(false);
+ expect(useTestStore.getState().isFullScreen).toBe(false);
+ });
+ });
+
+ describe("编辑/预览模式", () => {
+ test("setIsOnlyWrite 应切换仅编辑状态并关闭预览", () => {
+ // 初始状态
+ useTestStore.setState({ isOnlyPreview: true });
+
+ // 第一次切换
+ useTestStore.getState().setIsOnlyWrite();
+ expect(useTestStore.getState().isOnlyWrite).toBe(true);
+ expect(useTestStore.getState().isOnlyPreview).toBe(false);
+
+ // 再次切换
+ useTestStore.getState().setIsOnlyWrite();
+ expect(useTestStore.getState().isOnlyWrite).toBe(false);
+ });
+
+ test("setIsOnlyPreview 应切换仅预览状态并关闭编辑", () => {
+ // 初始状态
+ useTestStore.setState({ isOnlyWrite: true });
+
+ // 第一次切换
+ useTestStore.getState().setIsOnlyPreview();
+ expect(useTestStore.getState().isOnlyPreview).toBe(true);
+ expect(useTestStore.getState().isOnlyWrite).toBe(false);
+
+ // 再次切换
+ useTestStore.getState().setIsOnlyPreview();
+ expect(useTestStore.getState().isOnlyPreview).toBe(false);
+ });
+ });
+
+ describe("侧边栏控制", () => {
+ test("设置相同标记应切换显示状态", () => {
+ const mark = "settings";
+
+ // 第一次设置
+ useTestStore.getState().setSidebar(MockComponent, mark);
+ expect(useTestStore.getState().isSidebar).toBe(true);
+ expect(useTestStore.getState().componentMark).toBe(mark);
+
+ // 相同标记再次设置
+ useTestStore.getState().setSidebar(MockComponent, mark);
+ expect(useTestStore.getState().isSidebar).toBe(false);
+ });
+
+ test("设置不同标记应更新组件", () => {
+ // 初始设置
+ useTestStore.getState().setSidebar(MockComponent, "settings");
+
+ // 设置不同标记
+ useTestStore.getState().setSidebar(New
, "help");
+ expect(useTestStore.getState().isSidebar).toBe(true);
+ expect(useTestStore.getState().componentMark).toBe("help");
+ });
+ });
+
+ describe("状态互斥测试", () => {
+ test("全屏模式不应影响其他状态", () => {
+ useTestStore.getState().setIsFullScreen(true);
+ useTestStore.getState().setIsOnlyWrite();
+ useTestStore.getState().setSidebar(MockComponent, "test");
+
+ const state = useTestStore.getState();
+ expect(state.isFullScreen).toBe(true);
+ expect(state.isOnlyWrite).toBe(true);
+ expect(state.isSidebar).toBe(true);
+ });
+
+ test("仅写和仅预览应互斥", () => {
+ useTestStore.getState().setIsOnlyWrite();
+ expect(useTestStore.getState().isOnlyPreview).toBe(false);
+
+ useTestStore.getState().setIsOnlyPreview();
+ expect(useTestStore.getState().isOnlyWrite).toBe(false);
+ expect(useTestStore.getState().isOnlyPreview).toBe(true);
+ });
+ });
+});