/** * 通用 UI 组件测试 */ import { describe, expect, it, vi } from "vitest"; import { render, screen, fireEvent } from "@testing-library/react"; import { PaperCard, PageHeader, Button, Input, Select, Badge, Table, TableRow, TableCell, EmptyState, LoadingState, ErrorState, Pagination, } from "./ui"; describe("PaperCard", () => { it("渲染 children", () => { render(内容); expect(screen.getByText("内容")).toBeInTheDocument(); }); it("支持自定义 className", () => { const { container } = render( 内容, ); expect(container.firstChild).toHaveClass("custom-class"); }); }); describe("PageHeader", () => { it("渲染标题", () => { render(); expect(screen.getByText("用户管理")).toBeInTheDocument(); }); it("渲染描述", () => { render(); expect(screen.getByText("管理所有用户")).toBeInTheDocument(); }); it("渲染操作按钮", () => { render(新建} />); expect(screen.getByText("新建")).toBeInTheDocument(); }); }); describe("Button", () => { it("默认 secondary variant", () => { render(); expect(screen.getByText("点击")).toBeInTheDocument(); }); it("点击触发 onClick", () => { const onClick = vi.fn(); render(); fireEvent.click(screen.getByText("点击")); expect(onClick).toHaveBeenCalledTimes(1); }); it("disabled 时不触发 onClick", () => { const onClick = vi.fn(); render( , ); fireEvent.click(screen.getByText("点击")); expect(onClick).not.toHaveBeenCalled(); }); it("支持所有 variant", () => { const { rerender } = render(); expect(screen.getByText("主按钮")).toBeInTheDocument(); rerender(); expect(screen.getByText("危险按钮")).toBeInTheDocument(); rerender(); expect(screen.getByText("幽灵按钮")).toBeInTheDocument(); }); }); describe("Input", () => { it("渲染输入框并支持输入", () => { render(); const input = screen.getByPlaceholderText("请输入"); fireEvent.change(input, { target: { value: "测试内容" } }); expect(input).toHaveValue("测试内容"); }); }); describe("Select", () => { it("渲染下拉框和选项", () => { render( , ); expect(screen.getByText("选项A")).toBeInTheDocument(); expect(screen.getByText("选项B")).toBeInTheDocument(); }); }); describe("Badge", () => { it("渲染 active 状态标签", () => { render(); expect(screen.getByText("启用")).toBeInTheDocument(); }); it("渲染 locked 状态标签", () => { render(); expect(screen.getByText("锁定")).toBeInTheDocument(); }); it("渲染公告相关状态", () => { const { rerender } = render(); expect(screen.getByText("草稿")).toBeInTheDocument(); rerender(); expect(screen.getByText("已发布")).toBeInTheDocument(); rerender(); expect(screen.getByText("已归档")).toBeInTheDocument(); }); it("渲染邀请码状态", () => { const { rerender } = render(); expect(screen.getByText("未使用")).toBeInTheDocument(); rerender(); expect(screen.getByText("已使用")).toBeInTheDocument(); rerender(); expect(screen.getByText("已过期")).toBeInTheDocument(); }); it("未知状态显示原始值", () => { render(); expect(screen.getByText("unknown-status")).toBeInTheDocument(); }); }); describe("Table", () => { it("渲染表头和数据行", () => { render( 张三 zhangsan@test.com
, ); expect(screen.getByText("姓名")).toBeInTheDocument(); expect(screen.getByText("邮箱")).toBeInTheDocument(); expect(screen.getByText("张三")).toBeInTheDocument(); expect(screen.getByText("zhangsan@test.com")).toBeInTheDocument(); }); }); describe("EmptyState", () => { it("渲染空状态消息", () => { render(); expect(screen.getByText("暂无数据")).toBeInTheDocument(); }); }); describe("LoadingState", () => { it("渲染加载中文案", () => { render(); expect(screen.getByText("加载中...")).toBeInTheDocument(); }); }); describe("ErrorState", () => { it("渲染错误消息", () => { render(); expect(screen.getByText("加载失败")).toBeInTheDocument(); }); it("提供 onRetry 时渲染重试按钮", () => { const onRetry = vi.fn(); render(); const retryBtn = screen.getByText("重试"); fireEvent.click(retryBtn); expect(onRetry).toHaveBeenCalledTimes(1); }); it("不提供 onRetry 时不渲染重试按钮", () => { render(); expect(screen.queryByText("重试")).not.toBeInTheDocument(); }); }); describe("Pagination", () => { it("渲染总数和页码", () => { render( {}} />, ); expect(screen.getByText(/共 45 条/)).toBeInTheDocument(); expect(screen.getByText(/第 2\/3 页/)).toBeInTheDocument(); }); it("第一页禁用上一页按钮", () => { render( {}} />, ); expect(screen.getByText("上一页")).toBeDisabled(); expect(screen.getByText("下一页")).not.toBeDisabled(); }); it("最后一页禁用下一页按钮", () => { render( {}} />, ); expect(screen.getByText("下一页")).toBeDisabled(); expect(screen.getByText("上一页")).not.toBeDisabled(); }); it("点击上一页/下一页触发 onPageChange", () => { const onPageChange = vi.fn(); render( , ); fireEvent.click(screen.getByText("上一页")); expect(onPageChange).toHaveBeenCalledWith(1); fireEvent.click(screen.getByText("下一页")); expect(onPageChange).toHaveBeenCalledWith(3); }); it("total 为 0 时显示第 1/1 页", () => { render( {}} />, ); expect(screen.getByText(/第 1\/1 页/)).toBeInTheDocument(); }); });