import { describe, test, expect } from 'vitest'; import { deriveVirtualRows, VIRTUAL_CHILD_PROPS } from './layers-virtual-rows'; describe('deriveVirtualRows', () => { test('returns one row per item, labelled by the registered field', () => { const rows = deriveVirtualRows('Features Grid', { features: [{ title: 'Fast' }, { title: 'Secure' }], }); expect(rows).toEqual([ { index: 0, label: 'Fast' }, { index: 1, label: 'Secure' }, ]); }); test('falls back to " N" when the label field is missing or blank', () => { const rows = deriveVirtualRows('Features Grid', { features: [{ title: '' }, { description: 'no title key' }], }); expect(rows).toEqual([ { index: 0, label: 'Feature 1' }, { index: 1, label: 'Feature 2' }, ]); }); test('trims and truncates a long label to 40 characters with an ellipsis', () => { const long = 'x'.repeat(60); const rows = deriveVirtualRows('Features Grid', { features: [{ title: ` ${long} ` }] }); expect(rows[0].label).toHaveLength(41); expect(rows[0].label.endsWith('…')).toBe(true); }); test('an unregistered component yields no rows', () => { expect(deriveVirtualRows('Heading', { text: 'hi' })).toEqual([]); }); test('a missing or non-array prop yields no rows instead of throwing', () => { expect(deriveVirtualRows('Tabs', {})).toEqual([]); expect(deriveVirtualRows('Tabs', { tabs: 'not an array' })).toEqual([]); expect(deriveVirtualRows('Tabs', { tabs: null })).toEqual([]); }); test('a non-object item still gets a fallback label', () => { expect(deriveVirtualRows('Menu', { links: ['raw string'] })).toEqual([ { index: 0, label: 'Link 1' }, ]); }); test('Hero, Call to Action and CTA Section derive rows from their shared ctas prop', () => { const ctas = [ { text: 'Get Started', href: '#', variant: 'primary' }, { text: 'Learn More', href: '#learn', variant: 'outline' }, ]; expect(deriveVirtualRows('Hero', { ctas })).toEqual([ { index: 0, label: 'Get Started' }, { index: 1, label: 'Learn More' }, ]); expect(deriveVirtualRows('Call to Action', { ctas })).toEqual([ { index: 0, label: 'Get Started' }, { index: 1, label: 'Learn More' }, ]); expect(deriveVirtualRows('CTA Section', { ctas })).toEqual([ { index: 0, label: 'Get Started' }, { index: 1, label: 'Learn More' }, ]); }); test('a CTA with no text falls back to "Button N"', () => { const rows = deriveVirtualRows('Hero', { ctas: [{ href: '#' }, { text: '', href: '#empty' }], }); expect(rows).toEqual([ { index: 0, label: 'Button 1' }, { index: 1, label: 'Button 2' }, ]); }); test('every registry entry has a non-empty prop, label and fallback', () => { for (const [name, spec] of Object.entries(VIRTUAL_CHILD_PROPS)) { expect(spec.prop, `${name}.prop`).toBeTruthy(); expect(spec.label, `${name}.label`).toBeTruthy(); expect(spec.fallback, `${name}.fallback`).toBeTruthy(); } }); });