/** * ───────────────────────────────────────────── * SPB Git — Personal Git Platform * ───────────────────────────────────────────── * Author : Simon-Pierre Boucher * Contact : contact@spboucher.ai * File : test/unit/diff.test.mjs * Purpose : Unit tests — unified diff parsing + git path unquoting * License : MIT © Simon-Pierre Boucher * ───────────────────────────────────────────── */ import { describe, it, expect } from 'vitest'; import { parseUnifiedDiff, unquoteGitPath } from '../../src/git/repo.mjs'; const SAMPLE = `diff --git a/src/app.js b/src/app.js index 1111111..2222222 100644 --- a/src/app.js +++ b/src/app.js @@ -1,4 +1,5 @@ const a = 1; -const b = 2; +const b = 3; +const c = 4; export { a, b }; diff --git a/new.txt b/new.txt new file mode 100644 index 0000000..3333333 --- /dev/null +++ b/new.txt @@ -0,0 +1,2 @@ +hello +world diff --git a/img.png b/img.png Binary files a/img.png and b/img.png differ `; describe('parseUnifiedDiff', () => { it('parses files, hunks, line numbers, and stats', () => { const files = parseUnifiedDiff(SAMPLE); expect(files).toHaveLength(3); const [modified, added, binary] = files; expect(modified.newPath).toBe('src/app.js'); expect(modified.status).toBe('modified'); expect(modified.additions).toBe(2); expect(modified.deletions).toBe(1); expect(modified.hunks).toHaveLength(1); const lines = modified.hunks[0].lines; expect(lines[0]).toMatchObject({ type: 'ctx', old: 1, new: 1 }); expect(lines[1]).toMatchObject({ type: 'del', old: 2, new: null }); expect(lines[2]).toMatchObject({ type: 'add', old: null, new: 2 }); expect(lines[3]).toMatchObject({ type: 'add', old: null, new: 3 }); expect(lines[4]).toMatchObject({ type: 'ctx', old: 3, new: 4 }); expect(added.status).toBe('added'); expect(added.additions).toBe(2); expect(binary.binary).toBe(true); }); it('handles empty input', () => { expect(parseUnifiedDiff('')).toEqual([]); }); }); describe('unquoteGitPath', () => { it('passes through plain paths', () => { expect(unquoteGitPath('src/app.js')).toBe('src/app.js'); }); it('decodes octal utf-8 escapes', () => { expect(unquoteGitPath('"docs/\\303\\251t\\303\\251.txt"')).toBe('docs/été.txt'); }); it('decodes simple escapes', () => { expect(unquoteGitPath('"a\\"b\\\\c"')).toBe('a"b\\c'); }); });