Felipe97/llama-cpp-compiled
01.2k
1import { DiffLineKind } from '$lib/enums';2import { computeLineDiff, type DiffLine, renderUnifiedDiff } from '$lib/utils';3import { describe, expect, it } from 'vitest';4 5describe('computeLineDiff', () => {6 it('returns empty for two empty inputs', () => {7 expect(computeLineDiff('', '')).toEqual([]);8 });9 10 it('marks every line as removed for an empty new text', () => {11 expect(computeLineDiff('a\nb\nc', '')).toEqual([12 { kind: 'remove', oldLine: 1, text: 'a' },13 { kind: 'remove', oldLine: 2, text: 'b' },14 { kind: 'remove', oldLine: 3, text: 'c' }15 ]);16 });17 18 it('marks every line as added for an empty old text', () => {19 expect(computeLineDiff('', 'a\nb')).toEqual([20 { kind: 'add', newLine: 1, text: 'a' },21 { kind: 'add', newLine: 2, text: 'b' }22 ]);23 });24 25 it('detects a single-line replace', () => {26 expect(computeLineDiff('old', 'new')).toEqual([27 { kind: 'add', newLine: 1, text: 'new' },28 { kind: 'remove', oldLine: 1, text: 'old' }29 ]);30 });31 32 it('preserves interleaved context around additions', () => {33 const oldText = ['a', 'b', 'c'].join('\n');34 const newText = ['a', 'b', 'B', 'c'].join('\n');35 36 expect(computeLineDiff(oldText, newText)).toEqual([37 { kind: 'context', newLine: 1, oldLine: 1, text: 'a' },38 { kind: 'context', newLine: 2, oldLine: 2, text: 'b' },39 { kind: 'add', newLine: 3, text: 'B' },40 { kind: 'context', newLine: 4, oldLine: 3, text: 'c' }41 ]);42 });43 44 it('preserves interleaved context around an isolated replace', () => {45 // Multi-line context around a one-line change -> the diff should46 // show context flanking the changed line at its natural position.47 const oldText = ['a', 'b', 'c', 'd'].join('\n');48 const newText = ['a', 'b', 'X', 'd'].join('\n');49 50 expect(computeLineDiff(oldText, newText)).toEqual([51 { kind: 'context', newLine: 1, oldLine: 1, text: 'a' },52 { kind: 'context', newLine: 2, oldLine: 2, text: 'b' },53 { kind: 'add', newLine: 3, text: 'X' },54 { kind: 'remove', oldLine: 3, text: 'c' },55 { kind: 'context', newLine: 4, oldLine: 4, text: 'd' }56 ]);57 });58 59 it('preserves interleaved context around removals', () => {60 const oldText = ['a', 'b', 'c', 'd'].join('\n');61 const newText = ['a', 'c', 'd'].join('\n');62 63 expect(computeLineDiff(oldText, newText)).toEqual([64 { kind: 'context', newLine: 1, oldLine: 1, text: 'a' },65 { kind: 'remove', oldLine: 2, text: 'b' },66 { kind: 'context', newLine: 2, oldLine: 3, text: 'c' },67 { kind: 'context', newLine: 3, oldLine: 4, text: 'd' }68 ]);69 });70 71 it('handles purely identical inputs', () => {72 const text = 'x\ny\nz';73 const result = computeLineDiff(text, text);74 75 expect(result).toEqual([76 { kind: 'context', newLine: 1, oldLine: 1, text: 'x' },77 { kind: 'context', newLine: 2, oldLine: 2, text: 'y' },78 { kind: 'context', newLine: 3, oldLine: 3, text: 'z' }79 ]);80 });81 82 it('strips a trailing newline on the old/new inputs', () => {83 expect(computeLineDiff('a\n', 'a\nb\n')).toEqual([84 { kind: 'context', newLine: 1, oldLine: 1, text: 'a' },85 { kind: 'add', newLine: 2, text: 'b' }86 ]);87 });88 89 it('normalizes trailing CR on each line', () => {90 expect(computeLineDiff('a\r\nb\r\n', 'a\nb')).toEqual([91 { kind: 'context', newLine: 1, oldLine: 1, text: 'a' },92 { kind: 'context', newLine: 2, oldLine: 2, text: 'b' }93 ]);94 });95 96 it('keeps line numbers monotonic across mixed add/remove/context', () => {97 const oldText = ['l1', 'l2', 'l3', 'l4', 'l5'].join('\n');98 const newText = ['l1', 'l2-EDIT', 'l3', 'l4-NEW', 'l5'].join('\n');99 const diff = computeLineDiff(oldText, newText);100 101 // Walk the diff: every oldLine must increase strictly, and every102 // newLine must increase strictly. Lines missing one side (add or103 // remove) carry no number on that side.104 let lastOld = 0;105 let lastNew = 0;106 107 for (const line of diff) {108 if (line.oldLine !== undefined) {109 expect(line.oldLine).toBeGreaterThan(lastOld);110 lastOld = line.oldLine;111 }112 113 if (line.newLine !== undefined) {114 expect(line.newLine).toBeGreaterThan(lastNew);115 lastNew = line.newLine;116 }117 }118 });119});120 121describe('renderUnifiedDiff', () => {122 it('returns empty string for empty diff', () => {123 expect(renderUnifiedDiff([])).toBe('');124 });125 126 it('prefixes each line with `+`, `-`, or a single space', () => {127 const lines: DiffLine[] = [128 { kind: DiffLineKind.CONTEXT, text: 'ctx' },129 { kind: DiffLineKind.ADD, text: 'plus' },130 { kind: DiffLineKind.REMOVE, text: 'minus' }131 ];132 133 expect(renderUnifiedDiff(lines)).toBe(' ctx\n+plus\n-minus');134 });135 136 it('ignores oldLine/newLine metadata when emitting prefixes', () => {137 const lines: DiffLine[] = [138 { kind: DiffLineKind.CONTEXT, newLine: 1, oldLine: 1, text: 'a' },139 { kind: DiffLineKind.ADD, newLine: 2, text: 'b' }140 ];141 142 expect(renderUnifiedDiff(lines)).toBe(' a\n+b');143 });144});145 