74 lines
2.0 KiB
TypeScript
74 lines
2.0 KiB
TypeScript
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
|
|||
|
|
import { autoplay } from '../src/autoplay.ts';
|
||
|
|
|
||
|
|
function fakeCarousel(count = 3) {
|
||
|
|
let index = 0;
|
||
|
|
return {
|
||
|
|
get index() {
|
||
|
|
return index;
|
||
|
|
},
|
||
|
|
count,
|
||
|
|
next: vi.fn(() => {
|
||
|
|
index = (index + 1) % count;
|
||
|
|
}),
|
||
|
|
prev: vi.fn(),
|
||
|
|
scrollToIndex: vi.fn(),
|
||
|
|
on: () => () => {},
|
||
|
|
destroy: vi.fn(),
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// jsdom has no matchMedia — stub it. reduce = whether reduce-motion matches.
|
||
|
|
function stubMatchMedia(reduce: boolean) {
|
||
|
|
vi.stubGlobal('matchMedia', (q: string) => ({
|
||
|
|
matches: reduce && q.includes('reduce'),
|
||
|
|
media: q,
|
||
|
|
addEventListener() {},
|
||
|
|
removeEventListener() {},
|
||
|
|
}));
|
||
|
|
}
|
||
|
|
|
||
|
|
beforeEach(() => {
|
||
|
|
vi.useFakeTimers();
|
||
|
|
stubMatchMedia(false);
|
||
|
|
});
|
||
|
|
afterEach(() => {
|
||
|
|
vi.useRealTimers();
|
||
|
|
vi.unstubAllGlobals();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('advances every interval', () => {
|
||
|
|
const c = fakeCarousel();
|
||
|
|
autoplay(c as never, { interval: 1000, root: document.createElement('div') });
|
||
|
|
vi.advanceTimersByTime(2000);
|
||
|
|
expect(c.next).toHaveBeenCalledTimes(2);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('pause on pointerenter, resume on pointerleave', () => {
|
||
|
|
const c = fakeCarousel();
|
||
|
|
const root = document.createElement('div');
|
||
|
|
autoplay(c as never, { interval: 1000, root });
|
||
|
|
root.dispatchEvent(new Event('pointerenter'));
|
||
|
|
vi.advanceTimersByTime(3000);
|
||
|
|
expect(c.next).not.toHaveBeenCalled();
|
||
|
|
root.dispatchEvent(new Event('pointerleave'));
|
||
|
|
vi.advanceTimersByTime(1000);
|
||
|
|
expect(c.next).toHaveBeenCalledTimes(1);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('does not start under prefers-reduced-motion', () => {
|
||
|
|
stubMatchMedia(true);
|
||
|
|
const c = fakeCarousel();
|
||
|
|
autoplay(c as never, { interval: 1000, root: document.createElement('div') });
|
||
|
|
vi.advanceTimersByTime(5000);
|
||
|
|
expect(c.next).not.toHaveBeenCalled();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('stop() halts and removes listeners', () => {
|
||
|
|
const c = fakeCarousel();
|
||
|
|
const stop = autoplay(c as never, { interval: 1000, root: document.createElement('div') });
|
||
|
|
stop();
|
||
|
|
vi.advanceTimersByTime(5000);
|
||
|
|
expect(c.next).not.toHaveBeenCalled();
|
||
|
|
});
|