import { describe, expect, it } from 'vitest'; import { lightTheme, darkTheme, presetThemes } from '../src/theme/presets'; import { createTheme } from '../src/theme/createTheme'; import type { ThemeTokens } from '../src/theme/tokens'; describe('预置主题(明亮 Bento 设计系统)', () => { it('lightTheme 与 darkTheme 关键色彩不同', () => { expect(lightTheme.colors.bgPrimary).not.toBe(darkTheme.colors.bgPrimary); expect(lightTheme.colors.fgPrimary).not.toBe(darkTheme.colors.fgPrimary); }); it('浅色背景为 #F6F7F9,暗色为 OLED 纯黑 #040508', () => { expect(lightTheme.colors.bgPrimary).toBe('#F6F7F9'); expect(darkTheme.colors.bgPrimary).toBe('#040508'); }); it('accent 为近黑白单色:浅色 #111318,暗色反转为 #F3F4F6', () => { expect(lightTheme.colors.accent).toBe('#111318'); expect(darkTheme.colors.accent).toBe('#F3F4F6'); }); it('accentLight 为 accent 的半透明底色(不再是靛蓝族)', () => { expect(lightTheme.colors.accentLight).toBe('rgba(17,19,24,0.08)'); expect(darkTheme.colors.accentLight).toBe('rgba(243,244,246,0.10)'); }); it('财务语义色:暗色整体提亮一档', () => { expect(lightTheme.colors.financial.income).toBe('#10B981'); expect(lightTheme.colors.financial.expense).toBe('#EF4444'); expect(lightTheme.colors.financial.transfer).toBe('#3B82F6'); expect(darkTheme.colors.financial.income).toBe('#34D399'); expect(darkTheme.colors.financial.expense).toBe('#F87171'); expect(darkTheme.colors.financial.transfer).toBe('#60A5FA'); }); it('圆角含 xl(24),卡片默认大圆角', () => { for (const theme of [lightTheme, darkTheme]) { expect(theme.radii.sm).toBe(8); expect(theme.radii.md).toBe(12); expect(theme.radii.lg).toBe(16); expect(theme.radii.xl).toBe(24); expect(theme.radii.full).toBe(9999); } }); it('字阶含 display(34),且不指定 fontFamily(系统字体)', () => { for (const theme of [lightTheme, darkTheme] as ThemeTokens[]) { expect(theme.typography.display.fontSize).toBe(34); expect(theme.typography.h1.fontSize).toBe(28); expect(theme.typography.h2.fontSize).toBe(22); expect(theme.typography.h3.fontSize).toBe(17); for (const key of ['display', 'h1', 'h2', 'h3', 'body', 'bodySmall', 'caption'] as const) { expect(theme.typography[key].fontFamily).toBeUndefined(); } } }); it('presetThemes 注册表含 light 与 dark', () => { expect(presetThemes.light).toBe(lightTheme); expect(presetThemes.dark).toBe(darkTheme); }); it('spacing/shadows 结构完整', () => { for (const theme of [lightTheme, darkTheme] as ThemeTokens[]) { expect(theme.spacing).toHaveProperty('xs'); expect(theme.spacing).toHaveProperty('xl'); expect(theme.shadows).toHaveProperty('sm'); expect(theme.shadows).toHaveProperty('lg'); } }); }); describe('createTheme 自定义主题工厂', () => { it('未覆盖时等价于 lightTheme', () => { const custom = createTheme({}); expect(custom.colors.bgPrimary).toBe(lightTheme.colors.bgPrimary); expect(custom.spacing).toEqual(lightTheme.spacing); }); it('覆盖 accent 颜色时其他颜色保留', () => { const custom = createTheme({ colors: { ...lightTheme.colors, accent: '#FF5722' } }); expect(custom.colors.accent).toBe('#FF5722'); expect(custom.colors.bgPrimary).toBe(lightTheme.colors.bgPrimary); expect(custom.colors.success).toBe(lightTheme.colors.success); }); it('覆盖 financial 子对象时深度合并', () => { const custom = createTheme({ colors: { ...lightTheme.colors, financial: { ...lightTheme.colors.financial, income: '#000' } } }); expect(custom.colors.financial.income).toBe('#000'); expect(custom.colors.financial.expense).toBe(lightTheme.colors.financial.expense); }); it('覆盖 spacing 部分键时其他键保留', () => { const custom = createTheme({ spacing: { ...lightTheme.spacing, lg: 32 } }); expect(custom.spacing.lg).toBe(32); expect(custom.spacing.md).toBe(lightTheme.spacing.md); }); });