|
|
@@ -0,0 +1,154 @@
|
|
|
+import { render, fireEvent } from '@testing-library/react'
|
|
|
+import { Button } from '@/components/ui/button'
|
|
|
+
|
|
|
+describe('Button', () => {
|
|
|
+ it('应该渲染按钮', () => {
|
|
|
+ const { getByText } = render(<Button>测试按钮</Button>)
|
|
|
+
|
|
|
+ expect(getByText('测试按钮')).toBeTruthy()
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该处理点击事件', () => {
|
|
|
+ const handleClick = jest.fn()
|
|
|
+ const { getByText } = render(
|
|
|
+ <Button onClick={handleClick}>点击我</Button>
|
|
|
+ )
|
|
|
+
|
|
|
+ const button = getByText('点击我')
|
|
|
+ fireEvent.click(button)
|
|
|
+
|
|
|
+ expect(handleClick).toHaveBeenCalled()
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该应用默认变体样式', () => {
|
|
|
+ const { container } = render(<Button>默认按钮</Button>)
|
|
|
+
|
|
|
+ const button = container.querySelector('button')
|
|
|
+ expect(button?.className).toContain('bg-primary')
|
|
|
+ expect(button?.className).toContain('text-primary-foreground')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该应用不同的变体样式', () => {
|
|
|
+ const { container: defaultContainer } = render(<Button variant="default">默认</Button>)
|
|
|
+ const { container: destructiveContainer } = render(<Button variant="destructive">危险</Button>)
|
|
|
+ const { container: outlineContainer } = render(<Button variant="outline">轮廓</Button>)
|
|
|
+ const { container: secondaryContainer } = render(<Button variant="secondary">次要</Button>)
|
|
|
+ const { container: ghostContainer } = render(<Button variant="ghost">幽灵</Button>)
|
|
|
+ const { container: linkContainer } = render(<Button variant="link">链接</Button>)
|
|
|
+
|
|
|
+ const defaultButton = defaultContainer.querySelector('button')
|
|
|
+ const destructiveButton = destructiveContainer.querySelector('button')
|
|
|
+ const outlineButton = outlineContainer.querySelector('button')
|
|
|
+ const secondaryButton = secondaryContainer.querySelector('button')
|
|
|
+ const ghostButton = ghostContainer.querySelector('button')
|
|
|
+ const linkButton = linkContainer.querySelector('button')
|
|
|
+
|
|
|
+ expect(defaultButton?.className).toContain('bg-primary')
|
|
|
+ expect(destructiveButton?.className).toContain('bg-destructive')
|
|
|
+ expect(outlineButton?.className).toContain('border-input')
|
|
|
+ expect(secondaryButton?.className).toContain('bg-secondary')
|
|
|
+ expect(ghostButton?.className).toContain('hover:bg-accent')
|
|
|
+ expect(linkButton?.className).toContain('text-primary')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该应用不同的大小样式', () => {
|
|
|
+ const { container: defaultContainer } = render(<Button size="default">默认</Button>)
|
|
|
+ const { container: smContainer } = render(<Button size="sm">小</Button>)
|
|
|
+ const { container: lgContainer } = render(<Button size="lg">大</Button>)
|
|
|
+ const { container: iconContainer } = render(<Button size="icon">图标</Button>)
|
|
|
+
|
|
|
+ const defaultButton = defaultContainer.querySelector('button')
|
|
|
+ const smButton = smContainer.querySelector('button')
|
|
|
+ const lgButton = lgContainer.querySelector('button')
|
|
|
+ const iconButton = iconContainer.querySelector('button')
|
|
|
+
|
|
|
+ expect(defaultButton?.className).toContain('h-10')
|
|
|
+ expect(smButton?.className).toContain('h-9')
|
|
|
+ expect(lgButton?.className).toContain('h-11')
|
|
|
+ expect(iconButton?.className).toContain('h-10 w-10')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该禁用按钮', () => {
|
|
|
+ const { container } = render(<Button disabled>禁用按钮</Button>)
|
|
|
+
|
|
|
+ const button = container.querySelector('button')
|
|
|
+ expect(button?.disabled).toBe(true)
|
|
|
+ expect(button?.className).toContain('[&[disabled]]:opacity-50')
|
|
|
+ expect(button?.className).toContain('[&[disabled]]:pointer-events-none')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该应用自定义类名', () => {
|
|
|
+ const { container } = render(
|
|
|
+ <Button className="custom-class">自定义样式</Button>
|
|
|
+ )
|
|
|
+
|
|
|
+ const button = container.querySelector('button')
|
|
|
+ expect(button?.className).toContain('custom-class')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该渲染子元素', () => {
|
|
|
+ const { getByText } = render(
|
|
|
+ <Button>
|
|
|
+ <span>图标</span>
|
|
|
+ 带图标的按钮
|
|
|
+ </Button>
|
|
|
+ )
|
|
|
+
|
|
|
+ expect(getByText('带图标的按钮')).toBeTruthy()
|
|
|
+ expect(getByText('图标')).toBeTruthy()
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该传递其他属性', () => {
|
|
|
+ const { container } = render(
|
|
|
+ <Button type="submit" data-testid="test-button">提交按钮</Button>
|
|
|
+ )
|
|
|
+
|
|
|
+ const button = container.querySelector('button')
|
|
|
+ expect(button?.type).toBe('submit')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该应用重置样式', () => {
|
|
|
+ const { container } = render(<Button>重置按钮</Button>)
|
|
|
+
|
|
|
+ const button = container.querySelector('button')
|
|
|
+ expect(button?.className).toContain('w-auto')
|
|
|
+ expect(button?.className).toContain('border-0')
|
|
|
+ expect(button?.className).toContain('text-inherit')
|
|
|
+ expect(button?.className).toContain('p-0')
|
|
|
+ expect(button?.className).toContain('m-0')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该组合变体样式和重置样式', () => {
|
|
|
+ const { container } = render(
|
|
|
+ <Button variant="outline" size="sm">组合样式</Button>
|
|
|
+ )
|
|
|
+
|
|
|
+ const button = container.querySelector('button')
|
|
|
+ expect(button?.className).toContain('border-input') // outline变体
|
|
|
+ expect(button?.className).toContain('h-9') // sm大小
|
|
|
+ expect(button?.className).toContain('w-auto') // 重置样式
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该处理焦点状态', () => {
|
|
|
+ const { container } = render(<Button>焦点按钮</Button>)
|
|
|
+
|
|
|
+ const button = container.querySelector('button')
|
|
|
+ expect(button?.className).toContain('focus-visible:outline-none')
|
|
|
+ expect(button?.className).toContain('focus-visible:ring-2')
|
|
|
+ expect(button?.className).toContain('focus-visible:ring-ring')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该应用过渡效果', () => {
|
|
|
+ const { container } = render(<Button>过渡按钮</Button>)
|
|
|
+
|
|
|
+ const button = container.querySelector('button')
|
|
|
+ expect(button?.className).toContain('transition-colors')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('应该正确处理disabled为false的情况', () => {
|
|
|
+ const { container } = render(<Button disabled={false}>非禁用按钮</Button>)
|
|
|
+
|
|
|
+ const button = container.querySelector('button')
|
|
|
+ expect(button?.disabled).toBe(false)
|
|
|
+ })
|
|
|
+})
|