UNPKG

@furystack/shades-common-components

Version:

Common UI components for FuryStack Shades

122 lines 5.7 kB
import { createInjector } from '@furystack/inject'; import { createComponent, flushUpdates, initializeShadeRoot } from '@furystack/shades'; import { usingAsync } from '@furystack/utils'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { Skeleton } from './skeleton.js'; describe('Skeleton', () => { let originalAnimate; let animateCalls; beforeEach(() => { document.body.innerHTML = '<div id="root"></div>'; animateCalls = []; originalAnimate = Element.prototype.animate; Element.prototype.animate = vi.fn((keyframes, options) => { animateCalls.push({ keyframes, options }); const mockAnimation = { onfinish: null, oncancel: null, cancel: vi.fn(), play: vi.fn(), pause: vi.fn(), finish: vi.fn(), addEventListener: vi.fn(), removeEventListener: vi.fn(), }; if (Array.isArray(keyframes) && keyframes.some((kf) => 'opacity' in kf)) { setTimeout(() => { if (mockAnimation.onfinish) { mockAnimation.onfinish({}); } }, 10); } return mockAnimation; }); }); afterEach(() => { document.body.innerHTML = ''; Element.prototype.animate = originalAnimate; vi.restoreAllMocks(); }); it('should render with correct initial state and default delay', async () => { await usingAsync(createInjector(), async (injector) => { const rootElement = document.getElementById('root'); initializeShadeRoot({ injector, rootElement, jsxElement: createComponent(Skeleton, null), }); await flushUpdates(); await new Promise((resolve) => setTimeout(resolve, 0)); const skeleton = document.querySelector('shade-skeleton'); expect(skeleton).not.toBeNull(); const skeletonDiv = document.querySelector('shade-skeleton div'); expect(skeletonDiv).not.toBeNull(); const computedStyle = window.getComputedStyle(skeletonDiv); expect(computedStyle.opacity).toBe('0'); expect(computedStyle.display).toBe('inline-block'); const fadeInCall = animateCalls.find((call) => Array.isArray(call.keyframes) && call.keyframes.some((kf) => 'opacity' in kf)); expect(fadeInCall).toBeDefined(); expect(fadeInCall?.options?.delay).toBe(1500); }); }); it('should use custom delay when provided', async () => { await usingAsync(createInjector(), async (injector) => { const rootElement = document.getElementById('root'); initializeShadeRoot({ injector, rootElement, jsxElement: createComponent(Skeleton, { delay: 500 }), }); await flushUpdates(); await new Promise((resolve) => setTimeout(resolve, 0)); const fadeInCall = animateCalls.find((call) => Array.isArray(call.keyframes) && call.keyframes.some((kf) => 'opacity' in kf)); expect(fadeInCall).toBeDefined(); expect(fadeInCall?.options?.delay).toBe(500); }); }); it('should start fade-in animation with correct parameters', async () => { await usingAsync(createInjector(), async (injector) => { const rootElement = document.getElementById('root'); initializeShadeRoot({ injector, rootElement, jsxElement: createComponent(Skeleton, { delay: 100 }), }); await flushUpdates(); await new Promise((resolve) => setTimeout(resolve, 0)); const fadeInCall = animateCalls.find((call) => Array.isArray(call.keyframes) && call.keyframes.length === 2 && call.keyframes[0].opacity === 0 && call.keyframes[1].opacity === 1); expect(fadeInCall).toBeDefined(); const options = fadeInCall?.options; expect(options.fill).toBe('forwards'); expect(options.duration).toBe(300); expect(options.easing).toBe('ease-out'); expect(options.delay).toBe(100); }); }); it('should start background animation with correct keyframes after fade-in completes', async () => { await usingAsync(createInjector(), async (injector) => { const rootElement = document.getElementById('root'); initializeShadeRoot({ injector, rootElement, jsxElement: createComponent(Skeleton, { delay: 0 }), }); await flushUpdates(); await new Promise((resolve) => setTimeout(resolve, 50)); const backgroundAnimation = animateCalls.find((call) => Array.isArray(call.keyframes) && call.keyframes.some((kf) => 'backgroundPosition' in kf)); expect(backgroundAnimation).toBeDefined(); const options = backgroundAnimation?.options; expect(options.duration).toBe(10000); expect(options.iterations).toBe(Infinity); const keyframes = backgroundAnimation?.keyframes; expect(keyframes).toHaveLength(3); expect(keyframes[0].backgroundPosition).toBe('0% 50%'); expect(keyframes[1].backgroundPosition).toBe('100% 50%'); expect(keyframes[2].backgroundPosition).toBe('0% 50%'); }); }); }); //# sourceMappingURL=skeleton.spec.js.map