You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
58 lines
1.7 KiB
58 lines
1.7 KiB
// @vitest-environment jsdom
|
|
|
|
import { describe, expect, it } from 'vitest';
|
|
import { createReducedMotionTracker } from '../reduced-motion.svelte';
|
|
|
|
describe('ReducedMotionTracker', () => {
|
|
it('initializes from the current matchMedia value', () => {
|
|
const tracker = createReducedMotionTracker();
|
|
// jsdom matchMedia defaults to matches=false for unknown queries.
|
|
expect(tracker.matches).toBe(false);
|
|
tracker.dispose();
|
|
});
|
|
|
|
it('dispose detaches the listener (idempotent)', () => {
|
|
const tracker = createReducedMotionTracker();
|
|
expect(() => tracker.dispose()).not.toThrow();
|
|
// second dispose is a no-op (no throw)
|
|
expect(() => tracker.dispose()).not.toThrow();
|
|
});
|
|
|
|
it('falls back to false when window.matchMedia is missing', () => {
|
|
const fakeWin = {} as unknown as Window;
|
|
const tracker = createReducedMotionTracker(fakeWin);
|
|
expect(tracker.matches).toBe(false);
|
|
// dispose without listeners is a no-op (no throw)
|
|
tracker.dispose();
|
|
});
|
|
|
|
it('reads from a custom target window', () => {
|
|
let attachedListeners = 0;
|
|
const fakeWin = {
|
|
matchMedia: (q: string) => {
|
|
expect(q).toBe('(prefers-reduced-motion: reduce)');
|
|
return {
|
|
matches: true,
|
|
media: q,
|
|
onchange: null,
|
|
addEventListener: () => {
|
|
attachedListeners++;
|
|
},
|
|
removeEventListener: () => {
|
|
attachedListeners--;
|
|
},
|
|
addListener: () => {},
|
|
removeListener: () => {},
|
|
dispatchEvent: () => false
|
|
} as MediaQueryList;
|
|
}
|
|
} as unknown as Window;
|
|
|
|
const tracker = createReducedMotionTracker(fakeWin);
|
|
expect(tracker.matches).toBe(true);
|
|
expect(attachedListeners).toBe(1);
|
|
tracker.dispose();
|
|
expect(attachedListeners).toBe(0);
|
|
});
|
|
});
|