78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
import { describe, expect, it, vi, afterEach } from 'vitest';
|
|
import { reveal } from './reveal';
|
|
|
|
class TestIntersectionObserver {
|
|
static instances: TestIntersectionObserver[] = [];
|
|
|
|
callback: IntersectionObserverCallback;
|
|
disconnect = vi.fn();
|
|
observe = vi.fn();
|
|
unobserve = vi.fn();
|
|
|
|
constructor(callback: IntersectionObserverCallback) {
|
|
this.callback = callback;
|
|
TestIntersectionObserver.instances.push(this);
|
|
}
|
|
|
|
trigger(target: Element, isIntersecting: boolean) {
|
|
this.callback(
|
|
[{ isIntersecting, target } as IntersectionObserverEntry],
|
|
this as unknown as IntersectionObserver
|
|
);
|
|
}
|
|
}
|
|
|
|
describe('reveal action', () => {
|
|
afterEach(() => {
|
|
TestIntersectionObserver.instances = [];
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
it('toggles visibility as the element enters and leaves the viewport', () => {
|
|
vi.stubGlobal('IntersectionObserver', TestIntersectionObserver);
|
|
vi.spyOn(window, 'matchMedia').mockReturnValue({
|
|
matches: false,
|
|
media: '(prefers-reduced-motion: reduce)',
|
|
onchange: null,
|
|
addListener: vi.fn(),
|
|
removeListener: vi.fn(),
|
|
addEventListener: vi.fn(),
|
|
removeEventListener: vi.fn(),
|
|
dispatchEvent: vi.fn()
|
|
} as MediaQueryList);
|
|
|
|
const node = document.createElement('div');
|
|
document.body.appendChild(node);
|
|
vi.spyOn(node, 'getBoundingClientRect').mockReturnValue({
|
|
width: 100,
|
|
height: 100,
|
|
top: window.innerHeight + 100,
|
|
right: 100,
|
|
bottom: window.innerHeight + 200,
|
|
left: 0,
|
|
x: 0,
|
|
y: window.innerHeight + 100,
|
|
toJSON() {
|
|
return {};
|
|
}
|
|
} as DOMRect);
|
|
|
|
const action = reveal(node, { delay: 40, distance: 32 });
|
|
const observer = TestIntersectionObserver.instances[0];
|
|
|
|
expect(node.classList.contains('reveal-ready')).toBe(true);
|
|
expect(node.classList.contains('reveal-visible')).toBe(false);
|
|
expect(node.style.getPropertyValue('--reveal-delay')).toBe('40ms');
|
|
expect(node.style.getPropertyValue('--reveal-distance')).toBe('32px');
|
|
|
|
observer.trigger(node, true);
|
|
expect(node.classList.contains('reveal-visible')).toBe(true);
|
|
|
|
observer.trigger(node, false);
|
|
expect(node.classList.contains('reveal-visible')).toBe(false);
|
|
|
|
action.destroy();
|
|
expect(observer.disconnect).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|