import { describe, it, expect, vi, beforeEach } from 'vitest' import { setActivePinia, createPinia } from 'pinia' import { ref } from 'vue' import { useThemeStore } from '@/store/theme' // Mock @vueuse/core vi.mock('@vueuse/core', () => ({ useStorage: vi.fn((key: string, defaultValue: any) => { const stored = localStorage.getItem(key) const initial = stored ? JSON.parse(stored) : defaultValue return ref(initial) }), usePreferredDark: vi.fn(() => ref(false)) })) // Mock theme presets vi.mock('@/assets/styles/theme/presets', () => ({ themeColorPresets: { blue: { primary: '#409EFF', primaryLight3: '#79BBFF', primaryLight5: '#A0CFFF', primaryLight7: '#C6E2FF', primaryLight9: '#ECF5FF', primaryDark2: '#337ECC' }, green: { primary: '#67C23A', primaryLight3: '#95D475', primaryLight5: '#B3E19D', primaryLight7: '#D1EDC4', primaryLight9: '#F0F9EB', primaryDark2: '#529B2E' } }, defaultThemeColor: 'blue' })) describe('Theme Store', () => { beforeEach(() => { // 清理 localStorage 和重置 mock localStorage.clear() vi.clearAllMocks() // 重新创建 pinia setActivePinia(createPinia()) // 清理 DOM 类 document.documentElement.classList.remove('dark', 'compact-mode') document.documentElement.removeAttribute('style') }) describe('初始状态', () => { it('mode 默认应该是 system', () => { const store = useThemeStore() expect(store.config.mode).toBe('system') }) it('colorScheme 默认应该是 blue', () => { const store = useThemeStore() expect(store.config.colorScheme).toBe('blue') }) it('fontSize 默认应该是 default', () => { const store = useThemeStore() expect(store.config.fontSize).toBe('default') }) it('compactMode 默认应该是 false', () => { const store = useThemeStore() expect(store.config.compactMode).toBe(false) }) }) describe('isDark 计算属性', () => { it('system 模式下应该跟随系统偏好', () => { const store = useThemeStore() // 默认系统偏好是 false (浅色) expect(store.isDark).toBe(false) }) it('dark 模式下应该返回 true', () => { const store = useThemeStore() store.setMode('dark') expect(store.isDark).toBe(true) }) it('light 模式下应该返回 false', () => { const store = useThemeStore() store.setMode('light') expect(store.isDark).toBe(false) }) }) describe('toggleDarkMode', () => { it('从 dark 模式切换应该变为 light', () => { const store = useThemeStore() store.setMode('dark') expect(store.config.mode).toBe('dark') store.toggleDarkMode() expect(store.config.mode).toBe('light') }) it('从 light 模式切换应该变为 dark', () => { const store = useThemeStore() store.setMode('light') expect(store.config.mode).toBe('light') store.toggleDarkMode() expect(store.config.mode).toBe('dark') }) it('toggleDarkMode 应该切换模式', () => { const store = useThemeStore() const initialMode = store.config.mode store.toggleDarkMode() expect(store.config.mode).not.toBe(initialMode) }) }) describe('setMode', () => { it('应该正确设置主题模式', () => { const store = useThemeStore() store.setMode('dark') expect(store.config.mode).toBe('dark') store.setMode('light') expect(store.config.mode).toBe('light') store.setMode('system') expect(store.config.mode).toBe('system') }) }) describe('setColorScheme', () => { it('应该正确设置主题色', () => { const store = useThemeStore() store.setColorScheme('green') expect(store.config.colorScheme).toBe('green') store.setColorScheme('blue') expect(store.config.colorScheme).toBe('blue') }) }) describe('currentColors', () => { it('应该返回当前主题色配置', () => { const store = useThemeStore() expect(store.currentColors).toBeDefined() expect(store.currentColors.primary).toBe('#409EFF') }) it('切换主题色后应该返回对应配置', () => { const store = useThemeStore() store.setColorScheme('green') expect(store.currentColors.primary).toBe('#67C23A') }) }) describe('setFontSize', () => { it('应该正确设置字体大小', () => { const store = useThemeStore() store.setFontSize('small') expect(store.config.fontSize).toBe('small') store.setFontSize('large') expect(store.config.fontSize).toBe('large') store.setFontSize('default') expect(store.config.fontSize).toBe('default') }) }) describe('toggleCompactMode', () => { it('应该切换紧凑模式', () => { const store = useThemeStore() expect(store.config.compactMode).toBe(false) store.toggleCompactMode() expect(store.config.compactMode).toBe(true) store.toggleCompactMode() expect(store.config.compactMode).toBe(false) }) }) describe('resetToDefault', () => { it('应该有 resetToDefault 方法', () => { const store = useThemeStore() expect(typeof store.resetToDefault).toBe('function') }) it('调用 resetToDefault 不应该抛出错误', () => { const store = useThemeStore() expect(() => store.resetToDefault()).not.toThrow() }) }) describe('applyTheme', () => { it('dark 模式应该添加 dark 类', () => { const store = useThemeStore() store.setMode('dark') store.applyTheme() expect(document.documentElement.classList.contains('dark')).toBe(true) }) it('light 模式应该移除 dark 类', () => { const store = useThemeStore() document.documentElement.classList.add('dark') store.setMode('light') store.applyTheme() expect(document.documentElement.classList.contains('dark')).toBe(false) }) it('紧凑模式应该添加 compact-mode 类', () => { const store = useThemeStore() // 先确保紧凑模式为 false,然后切换 if (store.config.compactMode) { store.toggleCompactMode() } expect(store.config.compactMode).toBe(false) store.toggleCompactMode() expect(store.config.compactMode).toBe(true) store.applyTheme() expect(document.documentElement.classList.contains('compact-mode')).toBe(true) }) }) describe('themeColorPresets', () => { it('应该暴露主题色预设', () => { const store = useThemeStore() expect(store.themeColorPresets).toBeDefined() expect(store.themeColorPresets.blue).toBeDefined() expect(store.themeColorPresets.green).toBeDefined() }) }) })