numstat.spec.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. /** Numstat parsing and hunk line counting. */
  2. import { describe, expect, it } from 'vitest'
  3. import { fileDiffsOf, hunkLineCounts, parseNumstat } from '../src/numstat.ts'
  4. describe('parseNumstat', () => {
  5. it('reads plain, binary, and rename records', () => {
  6. const output = ['3\t1\tsrc/a.ts', '-\t-\timg.png', '2\t0\t', 'old.txt', 'new.txt', ''].join('\u0000')
  7. expect(parseNumstat(output)).toEqual([
  8. { path: 'src/a.ts', added: 3, deleted: 1, binary: false },
  9. { path: 'img.png', added: 0, deleted: 0, binary: true },
  10. { path: 'new.txt', added: 2, deleted: 0, binary: false },
  11. ])
  12. })
  13. it('returns nothing for empty output', () => {
  14. expect(parseNumstat('')).toEqual([])
  15. })
  16. it('rejects output without a final terminator or with malformed records', () => {
  17. expect(() => parseNumstat('1\t1\ta.txt')).toThrow('NUL-terminated')
  18. expect(() => parseNumstat('garbage\0')).toThrow('malformed numstat record')
  19. expect(() => parseNumstat('1\t0\t\0old.txt\0')).toThrow('rename')
  20. })
  21. })
  22. describe('hunkLineCounts', () => {
  23. it('counts changed lines and ignores context', () => {
  24. expect(hunkLineCounts([
  25. { path: 'a', oldText: 'keep\nold\nkeep', newText: 'keep\nnew\nnew2\nkeep' },
  26. { path: 'a', oldText: null, newText: 'x\ny\n' },
  27. ])).toEqual({ added: 4, deleted: 1 })
  28. })
  29. })
  30. describe('fileDiffsOf', () => {
  31. it('narrows the file-tool metadata and rejects anything else', () => {
  32. expect(fileDiffsOf({ diffs: [{ path: 'a', oldText: null, newText: 'b' }] })).toEqual([{ path: 'a', oldText: null, newText: 'b' }])
  33. expect(fileDiffsOf(undefined)).toBeUndefined()
  34. expect(fileDiffsOf([])).toBeUndefined()
  35. expect(fileDiffsOf({ diffs: [] })).toBeUndefined()
  36. expect(fileDiffsOf({ diffs: [null] })).toBeUndefined()
  37. expect(fileDiffsOf({ diffs: [{ path: 1, oldText: null, newText: '' }] })).toBeUndefined()
  38. expect(fileDiffsOf({ diffs: [{ path: 'a', oldText: 2, newText: '' }] })).toBeUndefined()
  39. expect(fileDiffsOf({ diffs: [{ path: 'a', oldText: 'x', newText: 3 }] })).toBeUndefined()
  40. })
  41. })