import { describe, expect, it } from 'vitest'; import { annotateUiSource, uiSourcePlugin } from './ui-source-plugin'; const root = '/private/work/project/ui'; const id = `${root}/src/screens/Panel.tsx`; const annotate = (code: string, filename = id) => annotateUiSource(code, filename, root); describe('UI source annotation', () => { it('records original one-based locations and preserves the original TSX', () => { const input = 'export function Panel() {\n return
;\n}\n'; const output = annotate(input)!; expect(output).toContain('
'); expect(output).toContain(''); expect(output.replace(/ data-ui-(?:source|component)="[^"]*"/g, '')).toBe(input); const metadata = output.match(/ data-ui-(?:source|component)="[^"]*"/g)!.join(''); expect(metadata).not.toMatch(/private|secret|token/); }); it('handles fragments, nested callbacks, arrows and wrapped components', () => { const output = annotate('const Panel = memo(() => <>
{items.map(item => )}
);')!; expect(output.match(/data-ui-component="Panel"/g)).toHaveLength(2); expect(output).toContain(''); expect(output).not.toContain('<> data'); }); it('respects manually supplied attributes individually', () => { const output = annotate('function Panel() { return
; }')!; expect(output.match(/data-ui-source=/g)).toHaveLength(1); expect(output.match(/data-ui-component=/g)).toHaveLength(1); expect(output).toContain('data-ui-source="manual" data-ui-component="Custom"'); }); it.each(['src/Panel.test.tsx', 'src/Panel.spec.tsx', 'src/test/Panel.tsx', 'src/__tests__/Panel.tsx', 'src/vendor/Panel.tsx', 'node_modules/Panel.tsx', 'src/Panel.ts', '../outside.tsx', 'src/Panel.tsx?raw'])('excludes %s', (file) => { expect(annotate('const Panel = () =>
', `${root}/${file}`)).toBeNull(); }); it('omits missing component names and escapes metadata paths', () => { expect(annotate('
')!).not.toContain('data-ui-component'); expect(annotate('
', `${root}/src/a"b.tsx`)).toContain('a"b.tsx:1:1'); }); it('marks raw HTML hosts without collecting their HTML or annotating custom components', () => { const input = 'function Preview() { return <>
; }'; const output = annotate(input)!; expect(output.match(/data-ui-content-boundary="true"/g)).toHaveLength(2); expect(output).toContain(''); expect(output.replace(/ data-ui-(?:source|component|content-boundary)="[^"]*"/g, '')).toBe(input); }); it('does not duplicate an explicit raw HTML boundary marker', () => { const output = annotate('
')!; expect(output.match(/data-ui-content-boundary=/g)).toHaveLength(1); }); it('runs before React transforms', () => { expect(uiSourcePlugin(root).enforce).toBe('pre'); }); });