91 lines
2.6 KiB
TypeScript
91 lines
2.6 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { generatePatch } from '../src/patch.js';
|
|
|
|
const A = `Component: Button
|
|
Props:
|
|
size: "md"
|
|
variant: "primary"
|
|
Styles:
|
|
background: #0066FF
|
|
borderRadius: 8px
|
|
`;
|
|
|
|
const B = `Component: Button
|
|
Props:
|
|
size: "lg"
|
|
variant: "primary"
|
|
Styles:
|
|
background: #0066FF
|
|
borderRadius: 12px
|
|
`;
|
|
|
|
describe('generatePatch', () => {
|
|
it('returns empty string for identical inputs', () => {
|
|
expect(generatePatch(A, A)).toBe('');
|
|
});
|
|
|
|
it('returns empty string for two empty strings', () => {
|
|
expect(generatePatch('', '')).toBe('');
|
|
});
|
|
|
|
it('includes --- and +++ headers', () => {
|
|
const patch = generatePatch(A, B);
|
|
expect(patch).toMatch(/^--- a\//m);
|
|
expect(patch).toMatch(/^\+\+\+ b\//m);
|
|
});
|
|
|
|
it('includes @@ hunk header', () => {
|
|
const patch = generatePatch(A, B);
|
|
expect(patch).toMatch(/^@@ /m);
|
|
});
|
|
|
|
it('marks changed lines correctly', () => {
|
|
const patch = generatePatch(A, B);
|
|
expect(patch).toContain('- size: "md"');
|
|
expect(patch).toContain('+ size: "lg"');
|
|
expect(patch).toContain('- borderRadius: 8px');
|
|
expect(patch).toContain('+ borderRadius: 12px');
|
|
});
|
|
|
|
it('preserves unchanged lines as context', () => {
|
|
const patch = generatePatch(A, B);
|
|
expect(patch).toContain(' variant: "primary"');
|
|
});
|
|
|
|
it('uses custom filename in headers', () => {
|
|
const patch = generatePatch(A, B, { filename: 'Button.tsx' });
|
|
expect(patch).toContain('--- a/Button.tsx');
|
|
expect(patch).toContain('+++ b/Button.tsx');
|
|
});
|
|
|
|
it('handles all-insert (empty before)', () => {
|
|
const patch = generatePatch('', 'line1\nline2\n');
|
|
expect(patch).toContain('+line1');
|
|
expect(patch).toContain('+line2');
|
|
});
|
|
|
|
it('handles all-delete (empty after)', () => {
|
|
const patch = generatePatch('line1\nline2\n', '');
|
|
expect(patch).toContain('-line1');
|
|
expect(patch).toContain('-line2');
|
|
});
|
|
|
|
it('produces multiple hunks when changes are far apart', () => {
|
|
const before = Array.from({ length: 20 }, (_, i) => `line${i}`).join('\n') + '\n';
|
|
const after = before
|
|
.replace('line0', 'CHANGED0')
|
|
.replace('line19', 'CHANGED19');
|
|
const patch = generatePatch(before, after);
|
|
const hunkCount = (patch.match(/^@@/gm) ?? []).length;
|
|
expect(hunkCount).toBe(2);
|
|
});
|
|
|
|
it('merges nearby hunks into one', () => {
|
|
const before = Array.from({ length: 10 }, (_, i) => `line${i}`).join('\n') + '\n';
|
|
const after = before.replace('line0', 'X').replace('line1', 'Y');
|
|
const patch = generatePatch(before, after);
|
|
const hunkCount = (patch.match(/^@@/gm) ?? []).length;
|
|
expect(hunkCount).toBe(1);
|
|
});
|
|
});
|