import { render } from '@testing-library/react'; import { describe, it, expect, vi } from 'vitest'; import { Slide } from './slide'; import { RevealContext } from '../reveal-context'; describe('Slide', () => { it('renders as a
element', () => { const { container } = render(Hello); const section = container.querySelector('section'); expect(section).toBeInTheDocument(); expect(section).toHaveTextContent('Hello'); }); it('passes data-* attributes through', () => { const { container } = render( Content ); const section = container.querySelector('section'); expect(section).toHaveAttribute('data-background', '#ff0000'); expect(section).toHaveAttribute('data-transition', 'zoom'); expect(section).toHaveAttribute('data-auto-animate', ''); }); it('maps background shorthand props to slide data attributes', () => { const { container } = render( Content ); const section = container.querySelector('section'); expect(section).toHaveAttribute('data-background', '#111827'); expect(section).toHaveAttribute('data-background-image', 'https://example.com/hero.png'); expect(section).toHaveAttribute('data-background-color', '#000000'); expect(section).toHaveAttribute('data-background-opacity', '0.4'); expect(section).toHaveAttribute('data-background-transition', 'zoom'); expect(section).toHaveAttribute('data-background-video-loop', ''); }); it('maps visibility and auto-animate shorthand props to slide data attributes', () => { const { container } = render( Content ); const section = container.querySelector('section'); expect(section).toHaveAttribute('data-visibility', 'hidden'); expect(section).toHaveAttribute('data-auto-animate', ''); expect(section).toHaveAttribute('data-auto-animate-id', 'hero'); expect(section).toHaveAttribute('data-auto-animate-restart', ''); expect(section).toHaveAttribute('data-auto-animate-unmatched', 'false'); expect(section).toHaveAttribute('data-auto-animate-easing', 'ease-out'); expect(section).toHaveAttribute('data-auto-animate-duration', '0.6'); expect(section).toHaveAttribute('data-auto-animate-delay', '0.1'); }); it('maps common Reveal slide shorthand props to data attributes', () => { const { container } = render( Content ); const section = container.querySelector('section'); expect(section).toHaveAttribute('data-transition', 'zoom-in fade-out'); expect(section).toHaveAttribute('data-transition-speed', 'fast'); expect(section).toHaveAttribute('data-autoslide', '1500'); expect(section).toHaveAttribute('data-notes', 'Speaker notes'); expect(section).toHaveAttribute('data-background-interactive', ''); expect(section).toHaveAttribute('data-preload', ''); }); it('prefers explicit data-* attributes over shorthand props', () => { const { container } = render( Content ); const section = container.querySelector('section'); expect(section).toHaveAttribute('data-background', '#222222'); expect(section).toHaveAttribute('data-background-color', '#333333'); expect(section).toHaveAttribute('data-auto-animate', ''); expect(section).toHaveAttribute('data-visibility', 'uncounted'); expect(section).toHaveAttribute('data-transition', 'fade'); expect(section).toHaveAttribute('data-notes', 'Raw notes'); expect(section).toHaveAttribute('data-preload', ''); }); it('applies className and style', () => { const { container } = render( Styled ); const section = container.querySelector('section'); expect(section).toHaveClass('intro'); expect(section).toHaveStyle({ fontSize: '20px' }); }); it('passes id and aria attributes', () => { const { container } = render( Accessible ); const section = container.querySelector('section'); expect(section).toHaveAttribute('id', 'slide-1'); expect(section).toHaveAttribute('aria-label', 'Introduction'); }); it('renders children of any type', () => { const { container } = render(

Title

Paragraph

); const section = container.querySelector('section'); expect(section?.querySelector('h1')).toHaveTextContent('Title'); expect(section?.querySelector('p')).toHaveTextContent('Paragraph'); }); it('calls syncSlide when data-* attributes change after mount', () => { const deck = { syncSlide: vi.fn(), } as any; const { container, rerender } = render( Content ); const section = container.querySelector('section'); expect(section).toBeInTheDocument(); expect(deck.syncSlide).not.toHaveBeenCalled(); deck.syncSlide.mockClear(); rerender( Content ); expect(deck.syncSlide).toHaveBeenCalledTimes(1); expect(deck.syncSlide).toHaveBeenCalledWith(container.querySelector('section')); }); it('calls syncSlide when shorthand background props change after mount', () => { const deck = { syncSlide: vi.fn(), } as any; const { container, rerender } = render( Content ); expect(deck.syncSlide).not.toHaveBeenCalled(); deck.syncSlide.mockClear(); rerender( Content ); expect(deck.syncSlide).toHaveBeenCalledTimes(1); expect(deck.syncSlide).toHaveBeenCalledWith(container.querySelector('section')); }); it('calls syncSlide when shorthand Reveal slide props change after mount', () => { const deck = { syncSlide: vi.fn(), } as any; const { container, rerender } = render( Content ); expect(deck.syncSlide).not.toHaveBeenCalled(); deck.syncSlide.mockClear(); rerender( Content ); expect(deck.syncSlide).toHaveBeenCalledTimes(1); expect(deck.syncSlide).toHaveBeenCalledWith(container.querySelector('section')); }); it('does not call syncSlide on first render even when data-* attributes are present', () => { const deck = { syncSlide: vi.fn(), } as any; render( Content ); expect(deck.syncSlide).not.toHaveBeenCalled(); }); it('does not call syncSlide for non-data prop updates', () => { const deck = { syncSlide: vi.fn(), } as any; const { rerender } = render( Content ); deck.syncSlide.mockClear(); rerender( Content ); expect(deck.syncSlide).not.toHaveBeenCalled(); }); it('does not call syncSlide on mount when no data-* attributes are present', () => { const deck = { syncSlide: vi.fn(), } as any; render( Content ); expect(deck.syncSlide).not.toHaveBeenCalled(); }); });