theme.spec.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // @vitest-environment jsdom
  2. import { beforeEach, describe, expect, it } from 'vitest'
  3. import { ThemeService } from '@deepseek-ai/dsh-client-ui-theme/client'
  4. describe('ThemeService', () => {
  5. beforeEach(() => {
  6. document.body.removeAttribute('data-ds-dark-theme')
  7. document.body.removeAttribute('style')
  8. })
  9. it('starts on light; apply toggles the dark body attribute both ways', () => {
  10. const theme = new ThemeService()
  11. expect(theme.current()).toBe('light')
  12. theme.apply('dark')
  13. expect(document.body.hasAttribute('data-ds-dark-theme')).toBe(true)
  14. expect(theme.current()).toBe('dark')
  15. theme.apply('light')
  16. expect(document.body.hasAttribute('data-ds-dark-theme')).toBe(false)
  17. expect(theme.current()).toBe('light')
  18. })
  19. it('throws on unregistered apply and duplicate register (built-ins included)', () => {
  20. const theme = new ThemeService()
  21. expect(() => { theme.apply('sepia') }).toThrow('not registered')
  22. expect(() => theme.register('light', {})).toThrow('already registered')
  23. theme.register('sepia', {})
  24. expect(() => theme.register('sepia', {})).toThrow('already registered')
  25. })
  26. it('applies third-party token overrides as body inline vars and swaps them on switch', () => {
  27. const theme = new ThemeService()
  28. theme.register('sepia', { '--dsw-alias-bg-base': 'rgb(1, 2, 3)' })
  29. theme.apply('sepia')
  30. expect(document.body.style.getPropertyValue('--dsw-alias-bg-base')).toBe('rgb(1, 2, 3)')
  31. expect(document.body.hasAttribute('data-ds-dark-theme')).toBe(false)
  32. theme.apply('dark')
  33. expect(document.body.style.getPropertyValue('--dsw-alias-bg-base')).toBe('')
  34. expect(document.body.hasAttribute('data-ds-dark-theme')).toBe(true)
  35. })
  36. it('disposing the active theme reverts to light; disposer is idempotent', () => {
  37. const theme = new ThemeService()
  38. const dispose = theme.register('sepia', { '--dsw-alias-bg-base': 'red' })
  39. theme.apply('sepia')
  40. dispose()
  41. expect(theme.current()).toBe('light')
  42. expect(document.body.style.getPropertyValue('--dsw-alias-bg-base')).toBe('')
  43. expect(() => { theme.apply('sepia') }).toThrow('not registered')
  44. dispose()
  45. expect(theme.current()).toBe('light')
  46. })
  47. it('disposing an inactive theme leaves the active selection untouched', () => {
  48. const theme = new ThemeService()
  49. const dispose = theme.register('sepia', {})
  50. theme.apply('dark')
  51. dispose()
  52. expect(theme.current()).toBe('dark')
  53. expect(document.body.hasAttribute('data-ds-dark-theme')).toBe(true)
  54. })
  55. })