ThemeSwitch.spec.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import { describe, it, expect, vi, beforeEach } from 'vitest'
  2. import { mount, flushPromises } from '@vue/test-utils'
  3. import { createPinia, setActivePinia } from 'pinia'
  4. import ThemeSwitch from '@/components/ThemeSwitch.vue'
  5. import { useThemeStore } from '@/store/theme'
  6. // Mock @vueuse/core
  7. vi.mock('@vueuse/core', () => ({
  8. useStorage: vi.fn((key, defaultValue) => {
  9. return { value: defaultValue }
  10. }),
  11. usePreferredDark: vi.fn(() => ({ value: false }))
  12. }))
  13. describe('ThemeSwitch Component', () => {
  14. beforeEach(() => {
  15. setActivePinia(createPinia())
  16. vi.clearAllMocks()
  17. })
  18. const mountThemeSwitch = () => {
  19. return mount(ThemeSwitch, {
  20. global: {
  21. plugins: [createPinia()],
  22. stubs: {
  23. 'el-tooltip': {
  24. template: '<div class="el-tooltip"><slot /></div>',
  25. props: ['effect', 'content', 'placement']
  26. },
  27. 'el-button': {
  28. template: '<button class="switch-btn" @click="$emit(\'click\')"><slot /></button>',
  29. props: ['circle', 'text']
  30. },
  31. 'el-icon': { template: '<span class="el-icon"><slot /></span>', props: ['size'] },
  32. Moon: { template: '<span class="icon-moon">Moon</span>' },
  33. Sunny: { template: '<span class="icon-sunny">Sunny</span>' },
  34. Setting: { template: '<span class="icon-setting">Setting</span>' }
  35. }
  36. }
  37. })
  38. }
  39. describe('渲染', () => {
  40. it('应该正确渲染主题切换组件', () => {
  41. const wrapper = mountThemeSwitch()
  42. expect(wrapper.find('.theme-switch').exists()).toBe(true)
  43. })
  44. it('应该显示两个按钮', () => {
  45. const wrapper = mountThemeSwitch()
  46. const buttons = wrapper.findAll('.switch-btn')
  47. expect(buttons.length).toBe(2)
  48. })
  49. it('浅色模式下应该显示太阳图标', () => {
  50. const wrapper = mountThemeSwitch()
  51. expect(wrapper.find('.icon-sunny').exists()).toBe(true)
  52. })
  53. })
  54. describe('主题切换', () => {
  55. it('点击主题按钮应该能触发点击事件', async () => {
  56. const wrapper = mountThemeSwitch()
  57. const buttons = wrapper.findAll('.switch-btn')
  58. expect(buttons.length).toBeGreaterThan(0)
  59. // 验证按钮可以被点击
  60. await buttons[0].trigger('click')
  61. // 验证没有抛出错误
  62. expect(true).toBe(true)
  63. })
  64. it('主题按钮应该存在', () => {
  65. const wrapper = mountThemeSwitch()
  66. const themeButton = wrapper.findAll('.switch-btn')[0]
  67. expect(themeButton.exists()).toBe(true)
  68. })
  69. })
  70. describe('设置按钮', () => {
  71. it('点击设置按钮应该触发 openSettings 事件', async () => {
  72. const wrapper = mountThemeSwitch()
  73. const buttons = wrapper.findAll('.switch-btn')
  74. await buttons[1].trigger('click')
  75. expect(wrapper.emitted('openSettings')).toBeTruthy()
  76. })
  77. })
  78. describe('提示信息', () => {
  79. it('应该显示切换模式的提示', () => {
  80. const wrapper = mountThemeSwitch()
  81. expect(wrapper.findAll('.el-tooltip').length).toBeGreaterThan(0)
  82. })
  83. })
  84. })