37 lines
1.6 KiB
TypeScript
37 lines
1.6 KiB
TypeScript
import { act, renderHook } from '@testing-library/react'
|
|
import { afterEach, expect, it, vi } from 'vitest'
|
|
import { useTheme } from '../../src/hooks/useTheme'
|
|
import { useSettingsStore } from '../../src/stores/settingsStore'
|
|
import { darkColors, lightColors } from '../../src/themes/app-theme'
|
|
|
|
afterEach(() => vi.unstubAllGlobals())
|
|
|
|
it('keeps the returned theme, surfaces and borders synchronized with system changes', () => {
|
|
let matches = false
|
|
const listeners = new Set<() => void>()
|
|
vi.stubGlobal('matchMedia', () => ({
|
|
get matches() {
|
|
return matches
|
|
},
|
|
addEventListener: (_event: string, listener: () => void) => listeners.add(listener),
|
|
removeEventListener: (_event: string, listener: () => void) => listeners.delete(listener),
|
|
}))
|
|
const original = useSettingsStore.getState().settings
|
|
useSettingsStore.setState({ settings: { ...original, theme: 'system' } })
|
|
const { result, unmount } = renderHook(() => useTheme())
|
|
expect(result.current.effective).toBe('light')
|
|
expect(document.documentElement.style.getPropertyValue('--hairline')).toBe(lightColors.hairline)
|
|
act(() => {
|
|
matches = true
|
|
listeners.forEach((listener) => listener())
|
|
})
|
|
expect(result.current.effective).toBe('dark')
|
|
expect(document.documentElement.dataset.theme).toBe('dark')
|
|
expect(document.documentElement.style.getPropertyValue('--hairline')).toBe(darkColors.hairline)
|
|
act(() => useSettingsStore.setState({ settings: { ...original, theme: 'light' } }))
|
|
expect(result.current.effective).toBe('light')
|
|
unmount()
|
|
expect(listeners.size).toBe(0)
|
|
useSettingsStore.setState({ settings: original })
|
|
})
|