import { describe, expect, it } from 'vitest'; import { applyHtmlEdits, applyEditsToNormalizedContent } from '@/lib/edit/html-edit'; const HTML = '\n\n\n\n\n\n\n\n'; describe('applyHtmlEdits (vendored pi edit core)', () => { it('applies a single exact str_replace edit', () => { const out = applyHtmlEdits(HTML, [ { oldText: 'getElementById("strt")', newText: 'getElementById("go")' }, ]); expect(out).toContain('getElementById("go").addEventListener'); expect(out).not.toContain('strt'); // everything else preserved expect(out).toContain(''); }); it('applies multiple non-overlapping edits in one call', () => { const out = applyHtmlEdits(HTML, [ { oldText: '', newText: '' }, { oldText: '"strt"', newText: '"go"' }, ]); expect(out).toContain('>Start<'); expect(out).toContain('getElementById("go")'); }); it('throws a not-found error when oldText is absent', () => { expect(() => applyHtmlEdits(HTML, [{ oldText: 'does-not-exist', newText: 'x' }])).toThrow( /Could not find/i, ); }); it('throws an ambiguity error when oldText is not unique', () => { expect(() => applyHtmlEdits('

x

\n

x

\n', [{ oldText: '

x

', newText: '

y

' }]), ).toThrow(/occurrences|unique/i); }); it('throws when an edit makes no change', () => { expect(() => applyHtmlEdits(HTML, [{ oldText: 'Go', newText: 'Go' }])).toThrow( /No changes|identical/i, ); }); it('fuzzy-matches smart quotes against ASCII oldText', () => { // content has a smart double-quote; oldText uses an ASCII quote const src = '

“hello”

\n'; const out = applyEditsToNormalizedContent(src, [{ oldText: '"hello"', newText: '"bye"' }], 'x'); expect(out.newContent).toContain('bye'); }); it('preserves CRLF line endings', () => { const crlf = '\r\nold\r\n'; const out = applyHtmlEdits(crlf, [{ oldText: 'old', newText: 'new' }]); expect(out).toContain('\r\n'); expect(out).toContain('new'); }); });