import { describe, it, expect } from 'vitest' import { render } from '@testing-library/react' import { readFileSync } from 'fs' import { fileURLToPath } from 'url' import { dirname, join } from 'path' import PhotoBand from './PhotoBand' const __dirname = dirname(fileURLToPath(import.meta.url)) describe('PhotoBand', () => { it('renders nothing when there are no images', () => { const { container } = render() expect(container.querySelector('.photo-band')).toBeNull() }) // The CSS animation translates the track by -50%. If the sequence is not // rendered exactly twice, the loop "jumps" instead of being seamless. it('renders the image sequence exactly twice for a seamless loop', () => { const images = ['/a.webp', '/b.webp', '/c.webp'] const { container } = render() const rendered = [...container.querySelectorAll('.photo-band-track img')].map(img => img.getAttribute('src') ) expect(rendered).toHaveLength(images.length * 2) // First half and second half must be identical and in original order. expect(rendered.slice(0, images.length)).toEqual(images) expect(rendered.slice(images.length)).toEqual(images) }) it('keeps the duplication invariant for any non-empty image list', () => { for (const n of [1, 2, 4, 7]) { const images = Array.from({ length: n }, (_, i) => `/img-${i}.webp`) const { container } = render() const count = container.querySelectorAll('.photo-band-track img').length expect(count).toBe(n * 2) } }) // Regression guard for the freeze bug: `width: auto` made the track width // depend on image decode timing, so before images loaded the track had ~0 // width and translateX(-50%) appeared frozen. The track image must have a // deterministic width that does not depend on the loaded image. it('does not use width:auto for band images (freeze-bug guard)', () => { const css = readFileSync(join(__dirname, '..', 'pages', 'Home.css'), 'utf-8') const imgRule = css.match(/\.photo-band-track img\s*\{([^}]*)\}/) expect(imgRule).not.toBeNull() const body = imgRule[1] expect(body).not.toMatch(/width:\s*auto/) expect(body).toMatch(/width:\s*\d/) }) })