import { describe, expect, it } from 'vitest'; import { foldSiblings } from '../fold'; import type { CSTNode } from '../../cst/types'; /** Build N identically-shaped interactive rows. */ function rows(n: number, role: 'button' = 'button'): CSTNode[] { return Array.from({ length: n }, (_, i) => ({ type: 'container' as const, role: 'section' as const, children: [ { type: 'interactive' as const, role, ref: `@e${i + 1}` as const, name: `Row ${i}` }, ], })); } describe('foldSiblings', () => { it('does not fold short chains (< 5)', () => { const { children, foldedCount } = foldSiblings(rows(4)); expect(foldedCount).toBe(0); expect(children).toHaveLength(4); }); it('folds a long chain of identical siblings', () => { const { children, foldedCount } = foldSiblings(rows(100)); expect(foldedCount).toBe(1); // 3 kept + 1 collapse marker. expect(children).toHaveLength(4); expect(children[3]).toEqual({ type: 'text', content: '[… 97 more similar items collapsed]', }); }); it('keeps the first 3 instances', () => { const { children } = foldSiblings(rows(20)); expect(children.slice(0, 3).every((n) => n.type === 'container')).toBe(true); }); it('does not fold structurally different siblings', () => { const mixed: CSTNode[] = [ { type: 'interactive', role: 'button', ref: '@e1', name: 'A' }, { type: 'interactive', role: 'textbox', ref: '@e2', name: 'B' }, { type: 'interactive', role: 'checkbox', ref: '@e3', name: 'C' }, { type: 'interactive', role: 'link', ref: '@e4', name: 'D' }, { type: 'interactive', role: 'select', ref: '@e5', name: 'E' }, { type: 'interactive', role: 'tab', ref: '@e6', name: 'F' }, ]; const { foldedCount, children } = foldSiblings(mixed); expect(foldedCount).toBe(0); expect(children).toHaveLength(6); }); it('folds nested repetitive lists too', () => { const table: CSTNode[] = [ { type: 'container', role: 'table', children: rows(50) }, ]; const { children, foldedCount } = foldSiblings(table); expect(foldedCount).toBe(1); const tableNode = children[0]; expect(tableNode.type).toBe('container'); if (tableNode.type === 'container') { expect(tableNode.children).toHaveLength(4); // 3 + marker } }); });