import test from 'node:test'; import assert from 'node:assert/strict'; import os from 'node:os'; import path from 'node:path'; import fs from 'node:fs/promises'; import { execFile } from 'node:child_process'; import { promisify } from 'node:util'; import gitModule from '../src/main/git-service.cjs'; const exec = promisify(execFile); const git = (args, cwd) => exec('git', args, { cwd, encoding: 'utf8' }); const { GitService, parseUnifiedDiff } = gitModule; test('unified diff parser separates selectable hunks', () => { const parsed = parseUnifiedDiff('diff --git a/a b/a\n--- a/a\n+++ b/a\n@@ -1 +1 @@\n-old\n+new\n@@ -10 +10 @@\n-x\n+y\n'); assert.equal(parsed.hunks.length, 2); assert.equal(parsed.hunks[0].additions, 1); assert.equal(parsed.hunks[1].deletions, 1); }); test('stages only selected hunks using a server-generated patch', async (t) => { const root = await fs.mkdtemp(path.join(os.tmpdir(), 'forgeflow-hunks-')); t.after(() => fs.rm(root, { recursive: true, force: true })); await git(['init'], root); await git(['config', 'user.name', 'ForgeFlow Test'], root); await git(['config', 'user.email', 'forgeflow@example.invalid'], root); const original = [...Array(20)].map((_, index) => `line ${index + 1}`).join('\n') + '\n'; await fs.writeFile(path.join(root, 'file.txt'), original); await git(['add', '.'], root); await git(['commit', '-m', 'Initial'], root); const lines = original.trimEnd().split('\n'); lines[0] = 'first changed'; lines[19] = 'last changed'; await fs.writeFile(path.join(root, 'file.txt'), `${lines.join('\n')}\n`); const service = new GitService(); const hunks = await service.diffHunks(root, 'file.txt'); assert.equal(hunks.hunks.length, 2); await service.stageHunks(root, 'file.txt', [0]); const staged = (await git(['diff', '--cached'], root)).stdout; const unstaged = (await git(['diff'], root)).stdout; assert.match(staged, /first changed/); assert.doesNotMatch(staged, /last changed/); assert.match(unstaged, /last changed/); assert.doesNotMatch(unstaged, /first changed/); await service.commitStaged(root, 'Commit reviewed hunk'); const afterCommit = (await git(['diff'], root)).stdout; assert.match(afterCommit, /last changed/); assert.doesNotMatch(afterCommit, /first changed/); });