| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- 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()
- })
- })
- })
|