= {
+ theme: "dark",
+ };
+
+ render(
+
+
+ ,
+ );
+
+ const displayedConfig = screen.getByTestId("config-value").textContent;
+
+ // 确保 "theme" 覆盖默认值
+ expect(displayedConfig).toContain('"theme":"dark"');
+
+ // 但其他默认配置仍然存在
+ Object.keys(defaultGlobalConfig).forEach((key) => {
+ if (key !== "theme") {
+ expect(displayedConfig).toContain(`"${key}":`);
+ }
+ });
+ });
+});
diff --git a/packages/mini-markdown-editor/src/components/providers/__test__/hotkeys-provider.test.tsx b/packages/mini-markdown-editor/src/components/providers/__test__/hotkeys-provider.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..72ec466c1a86cd0383a7c0bf738b005b4dc78197
--- /dev/null
+++ b/packages/mini-markdown-editor/src/components/providers/__test__/hotkeys-provider.test.tsx
@@ -0,0 +1,99 @@
+import { render, screen } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";
+import { useContext } from "react";
+import { describe, test, expect, vi, beforeEach } from "vitest";
+import { HotkeysProvider, HotkeysContext } from "../hotkeys-provider";
+import { Hotkey } from "@/common/hotkeys";
+
+// 测试组件:用于触发上下文方法
+const TestConsumer = ({ handle = () => console.log("It is pressed") }) => {
+ const { registerHandler, unregisterHandler, setEnabled } = useContext(HotkeysContext);
+ return (
+
+
+
+
+
+ );
+};
+
+describe("HotkeysProvider 组件测试", () => {
+ beforeEach(() => {
+ vi.restoreAllMocks();
+ });
+
+ // 测试基础功能
+ test("应正确提供上下文方法", () => {
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByText("Register Bold")).toBeInTheDocument();
+ expect(screen.getByText("Unregister Bold")).toBeInTheDocument();
+ });
+
+ // 测试快捷键注册与触发
+ test("当注册快捷键并触发时,应调用处理程序", async () => {
+ const mockHandler = vi.fn();
+ const user = userEvent.setup();
+
+ render(
+
+
+ ,
+ );
+
+ // 注册快捷键
+ await user.click(screen.getByText("Register Bold"));
+
+ // 触发快捷键
+ await user.keyboard("{Control>}b{/Control}");
+ expect(mockHandler).toHaveBeenCalledTimes(1);
+ });
+
+ // 测试禁用状态
+ test("当禁用快捷键时,处理程序不应被触发", async () => {
+ const mockHandler = vi.fn();
+ const user = userEvent.setup();
+
+ render(
+
+
+ ,
+ );
+
+ // 注册并禁用
+ await user.click(screen.getByText("Register Bold"));
+ await user.click(screen.getByText("Disable"));
+
+ // 触发快捷键
+ await user.keyboard("{Control>}b{/Control}");
+ expect(mockHandler).not.toHaveBeenCalled();
+ });
+
+ // 测试注销功能
+ test("当注销快捷键后,处理程序不再响应", async () => {
+ const mockHandler = vi.fn();
+ const user = userEvent.setup();
+
+ render(
+
+
+ ,
+ );
+
+ // 注册
+ await user.click(screen.getByText("Register Bold"));
+
+ // 触发快捷键
+ await user.keyboard("{Control>}b{/Control}");
+ expect(mockHandler).toHaveBeenCalledTimes(1);
+
+ // 注销
+ await user.click(screen.getByText("Unregister Bold"));
+ await user.keyboard("{Control>}b{/Control}");
+ expect(mockHandler).toHaveBeenCalledTimes(1); // 调用次数不变
+ });
+});
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..2a26151d465a0a57f98fb786c6ad56b0210e0b1f
--- /dev/null
+++ b/packages/mini-markdown-editor/src/components/providers/__test__/toolbar-provider.test.tsx
@@ -0,0 +1,92 @@
+import { render, screen } from "@testing-library/react";
+import { useContext, useEffect, useState } from "react";
+import { describe, test, expect, vi, beforeEach } from "vitest";
+import { ToolbarProvider, ToolbarContext } from "../toolbar-provider";
+import type { ToolbarContextValues, ToolbarItem } from "@/types/toolbar";
+import { toolbarConfig } from "@/config/toolbar";
+// 模拟工具栏配置模块
+vi.mock("@/config/toolbar", () => ({
+ toolbarConfig: {
+ getAllToolbars: vi.fn(() => [
+ { type: "file", title: "文件" },
+ { type: "edit", title: "编辑" },
+ ]),
+ },
+}));
+// 测试用消费者组件
+const TestConsumer = () => {
+ const context = useContext(ToolbarContext);
+ const [testItems, setTestItems] = useState([]);
+
+ useEffect(() => {
+ if (context?.toolbars) {
+ setTestItems(context.toolbars);
+ }
+ }, [context]);
+
+ return (
+
+
{testItems.length}
+
{testItems[0]?.title}
+
+ );
+};
+
+describe("ToolbarProvider 组件测试", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ test("应正确初始化工具栏配置", async () => {
+ // 渲染组件
+ render(
+
+
+ ,
+ );
+
+ // 验证初始化调用
+ expect(await screen.findByTestId("toolbar-count")).toHaveTextContent("2");
+ expect(await screen.findByTestId("first-toolbar")).toHaveTextContent("文件");
+ });
+
+ test("应提供有效的上下文值", () => {
+ let contextValue: ToolbarContextValues = { toolbars: [] };
+ // 直接访问上下文的辅助组件
+ const ContextChecker = () => {
+ contextValue = useContext(ToolbarContext)!;
+ return null;
+ };
+
+ render(
+
+
+ ,
+ );
+
+ expect(contextValue).toBeDefined();
+ expect(contextValue?.toolbars).toHaveLength(2);
+ expect(contextValue?.toolbars[1].type).toBe("edit");
+ });
+
+ test("应只在挂载时加载配置", async () => {
+ const { rerender } = render(
+
+
+ ,
+ );
+
+ // 初始调用
+ expect(vi.mocked(toolbarConfig.getAllToolbars)).toHaveBeenCalledTimes(1);
+
+ // 重新渲染
+ rerender(
+
+
+ ,
+ );
+
+ // 验证没有重复调用
+ expect(toolbarConfig.getAllToolbars).toHaveBeenCalledTimes(1);
+ });
+});