import { expect, tap } from '@git.zone/tstest/tapbundle'; import * as smartdiff from '../ts/index.js'; // ============================================================================= // Backward Compatibility Tests // ============================================================================= tap.test('createDiff and applyPatch should work (backward compatible)', async () => { const text1 = 'hi there'; const text2 = 'hi Polly, there is a Sandwich.'; const patch = smartdiff.createDiff(text1, text2); console.log('Compact diff:', patch); const result = smartdiff.applyPatch(text1, patch); console.log('Reconstructed:', result); expect(result).toEqual(text2); }); tap.test('createDiff should produce compact format', async () => { const original = 'Hello World'; const revised = 'Hello smart World'; const diff = smartdiff.createDiff(original, revised); const parsed = JSON.parse(diff); // Should be array of tuples expect(Array.isArray(parsed)).toBeTrue(); // Each tuple should have operation and value for (const item of parsed) { expect(Array.isArray(item)).toBeTrue(); expect(item.length).toEqual(2); expect([-1, 0, 1]).toContain(item[0]); } }); // ============================================================================= // Character Diff Tests // ============================================================================= tap.test('getCharDiff should return character-level diff segments', async () => { const original = 'hello'; const revised = 'hallo'; const segments = smartdiff.getCharDiff(original, revised); expect(Array.isArray(segments)).toBeTrue(); expect(segments.length).toBeGreaterThan(0); // Each segment should have type and value for (const segment of segments) { expect(['equal', 'insert', 'delete']).toContain(segment.type); expect(typeof segment.value).toEqual('string'); } // Should detect the 'e' -> 'a' change const deleteSegment = segments.find(s => s.type === 'delete'); const insertSegment = segments.find(s => s.type === 'insert'); expect(deleteSegment).toBeDefined(); expect(insertSegment).toBeDefined(); }); tap.test('formatCharDiffForConsole should produce ANSI colored output', async () => { const original = 'hello world'; const revised = 'hello beautiful world'; const output = smartdiff.formatCharDiffForConsole(original, revised); console.log('Char diff console output:', output); // Should contain ANSI codes expect(output).toInclude('\x1b['); // Should contain the unchanged parts expect(output).toInclude('hello'); expect(output).toInclude('world'); }); tap.test('formatCharDiffAsHtml should produce HTML spans', async () => { const original = 'hello'; const revised = 'hallo'; const html = smartdiff.formatCharDiffAsHtml(original, revised); console.log('Char diff HTML:', html); expect(html).toInclude(' { const original = 'line1\nline2\nline3'; const revised = 'line1\nmodified\nline3'; const lineDiff = smartdiff.getLineDiff(original, revised); console.log('Line diff:', lineDiff); expect(Array.isArray(lineDiff)).toBeTrue(); // Should have line numbers and types for (const line of lineDiff) { expect(typeof line.lineNumber).toEqual('number'); expect(['equal', 'insert', 'delete']).toContain(line.type); expect(typeof line.value).toEqual('string'); } }); tap.test('formatLineDiffForConsole should produce unified-style output', async () => { const original = 'function hello() {\n console.log("hi");\n}'; const revised = 'function hello() {\n console.log("hello world");\n}'; const output = smartdiff.formatLineDiffForConsole(original, revised); console.log('Line diff console output:\n' + output); // Should have +/- prefixes expect(output).toInclude('-'); expect(output).toInclude('+'); }); tap.test('formatLineDiffAsHtml should produce HTML divs', async () => { const original = 'a\nb\nc'; const revised = 'a\nB\nc'; const html = smartdiff.formatLineDiffAsHtml(original, revised); console.log('Line diff HTML:\n' + html); expect(html).toInclude('
'); expect(html).toInclude('