import { describe, it, expect } from 'vitest'; import { computeDiff, countChanges } from '../../../src/utils/diff.js'; describe('Diff - 差异比较扩展测试', () => { describe('computeDiff - 计算 diff', () => { it('新文件所有行都是添加', () => { const diff = computeDiff(null, 'line1\nline2\nline3'); expect(diff.isNew).toBe(true); expect(diff.oldContent).toBeNull(); expect(diff.hunks.length).toBe(1); expect(diff.hunks[0].lines.every(l => l.type === 'add')).toBe(true); expect(diff.hunks[0].newCount).toBe(3); }); it('相同内容返回空 hunks', () => { const content = 'line1\nline2\nline3'; const diff = computeDiff(content, content); expect(diff.isNew).toBe(false); // 相同内容可能没有实际变化的 hunks const hasChanges = diff.hunks.some(h => h.lines.some(l => l.type === 'add' || l.type === 'remove') ); expect(hasChanges).toBe(false); }); it('检测添加的行', () => { const oldContent = 'line1\nline2'; const newContent = 'line1\nline2\nline3'; const diff = computeDiff(oldContent, newContent); expect(diff.isNew).toBe(false); const addedLines = diff.hunks.flatMap(h => h.lines.filter(l => l.type === 'add')); expect(addedLines.some(l => l.content === 'line3')).toBe(true); }); it('检测删除的行', () => { const oldContent = 'line1\nline2\nline3'; const newContent = 'line1\nline2'; const diff = computeDiff(oldContent, newContent); const removedLines = diff.hunks.flatMap(h => h.lines.filter(l => l.type === 'remove')); expect(removedLines.some(l => l.content === 'line3')).toBe(true); }); it('检测修改的行(删除+添加)', () => { const oldContent = 'line1\nold line\nline3'; const newContent = 'line1\nnew line\nline3'; const diff = computeDiff(oldContent, newContent); const removedLines = diff.hunks.flatMap(h => h.lines.filter(l => l.type === 'remove')); const addedLines = diff.hunks.flatMap(h => h.lines.filter(l => l.type === 'add')); expect(removedLines.some(l => l.content === 'old line')).toBe(true); expect(addedLines.some(l => l.content === 'new line')).toBe(true); }); it('处理空文件', () => { const diff = computeDiff('', 'new content'); expect(diff.isNew).toBe(false); // 空到有内容是添加 const addedLines = diff.hunks.flatMap(h => h.lines.filter(l => l.type === 'add')); expect(addedLines.length).toBeGreaterThan(0); }); it('处理多个不连续的变更', () => { const oldContent = 'line1\nkeep1\nold2\nkeep2\nold3\nline6'; const newContent = 'line1\nkeep1\nnew2\nkeep2\nnew3\nline6'; const diff = computeDiff(oldContent, newContent); // 应该有变更 const changes = diff.hunks.flatMap(h => h.lines.filter(l => l.type === 'add' || l.type === 'remove') ); expect(changes.length).toBeGreaterThan(0); }); it('处理完全不同的内容', () => { const oldContent = 'completely\ndifferent\ncontent'; const newContent = 'totally\nnew\nstuff'; const diff = computeDiff(oldContent, newContent); expect(diff.hunks.length).toBeGreaterThan(0); }); }); describe('countChanges - 统计变更', () => { it('统计添加行数', () => { const diff = computeDiff(null, 'line1\nline2\nline3'); const changes = countChanges(diff); expect(changes.additions).toBe(3); expect(changes.deletions).toBe(0); }); it('统计删除行数', () => { const diff = computeDiff('line1\nline2\nline3', ''); const changes = countChanges(diff); expect(changes.deletions).toBe(3); }); it('统计混合变更', () => { const diff = computeDiff('old1\nold2', 'new1\nold2\nnew2'); const changes = countChanges(diff); // 具体数字取决于 diff 算法实现 expect(changes.additions).toBeGreaterThanOrEqual(0); expect(changes.deletions).toBeGreaterThanOrEqual(0); }); it('无变更返回零', () => { const diff = computeDiff('same', 'same'); const changes = countChanges(diff); expect(changes.additions + changes.deletions).toBe(0); }); }); });