Files
Genarrative/scripts/commit-task.test.ts

137 lines
4.4 KiB
TypeScript

import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { resolve } from 'node:path';
import { spawnSync } from 'node:child_process';
import { afterEach, describe, expect, it } from 'vitest';
function run(command: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv) {
return spawnSync(command, args, {
cwd,
encoding: 'utf8',
env: {
...process.env,
...env,
},
});
}
function mustRun(command: string, args: string[], cwd: string, env?: NodeJS.ProcessEnv) {
const result = run(command, args, cwd, env);
if (result.status !== 0) {
throw new Error(
`${command} ${args.join(' ')} failed:\n${result.stdout}\n${result.stderr}`,
);
}
return result;
}
describe('commit-task script', () => {
const tempDirs: string[] = [];
afterEach(() => {
while (tempDirs.length > 0) {
rmSync(tempDirs.pop()!, { recursive: true, force: true });
}
});
it('commits only the specified files', () => {
const repoRoot = mkdtempSync(resolve(tmpdir(), 'genarrative-commit-task-'));
tempDirs.push(repoRoot);
mustRun('git', ['init'], repoRoot);
mustRun('git', ['config', 'user.name', 'Codex Test'], repoRoot);
mustRun('git', ['config', 'user.email', 'codex@example.com'], repoRoot);
mkdirSync(resolve(repoRoot, 'docs'), { recursive: true });
mkdirSync(resolve(repoRoot, 'notes'), { recursive: true });
writeFileSync(resolve(repoRoot, 'docs', 'task.md'), 'v1\n', 'utf8');
writeFileSync(resolve(repoRoot, 'notes', 'other.md'), 'other v1\n', 'utf8');
mustRun('git', ['add', '.'], repoRoot);
mustRun('git', ['commit', '-m', 'init'], repoRoot);
writeFileSync(resolve(repoRoot, 'docs', 'task.md'), 'v2\n', 'utf8');
writeFileSync(resolve(repoRoot, 'notes', 'other.md'), 'other v2\n', 'utf8');
const scriptPath = resolve('/home/Genarrative/scripts/commit-task.mjs');
const commitResult = mustRun(
'node',
[scriptPath, '-m', '提交任务文件', 'docs/task.md'],
repoRoot,
{
GENARRATIVE_COMMIT_REPO_ROOT: repoRoot,
},
);
expect(commitResult.stdout).toContain('提交任务文件');
const committedTaskContent = mustRun(
'git',
['show', 'HEAD:docs/task.md'],
repoRoot,
).stdout;
expect(committedTaskContent).toBe('v2\n');
const committedOtherContent = mustRun(
'git',
['show', 'HEAD:notes/other.md'],
repoRoot,
).stdout;
expect(committedOtherContent).toBe('other v1\n');
const statusResult = mustRun('git', ['status', '--short'], repoRoot);
expect(statusResult.stdout).toContain(' M notes/other.md');
expect(statusResult.stdout).not.toContain('docs/task.md');
});
it('does not include unrelated staged files in the commit', () => {
const repoRoot = mkdtempSync(resolve(tmpdir(), 'genarrative-commit-task-'));
tempDirs.push(repoRoot);
mustRun('git', ['init'], repoRoot);
mustRun('git', ['config', 'user.name', 'Codex Test'], repoRoot);
mustRun('git', ['config', 'user.email', 'codex@example.com'], repoRoot);
mkdirSync(resolve(repoRoot, 'docs'), { recursive: true });
mkdirSync(resolve(repoRoot, 'notes'), { recursive: true });
writeFileSync(resolve(repoRoot, 'docs', 'task.md'), 'v1\n', 'utf8');
writeFileSync(resolve(repoRoot, 'notes', 'other.md'), 'other v1\n', 'utf8');
mustRun('git', ['add', '.'], repoRoot);
mustRun('git', ['commit', '-m', 'init'], repoRoot);
writeFileSync(resolve(repoRoot, 'docs', 'task.md'), 'v2\n', 'utf8');
writeFileSync(resolve(repoRoot, 'notes', 'other.md'), 'other v2\n', 'utf8');
mustRun('git', ['add', 'notes/other.md'], repoRoot);
const scriptPath = resolve('/home/Genarrative/scripts/commit-task.mjs');
mustRun(
'node',
[scriptPath, '-m', '只提交任务文件', 'docs/task.md'],
repoRoot,
{
GENARRATIVE_COMMIT_REPO_ROOT: repoRoot,
},
);
const committedTaskContent = mustRun(
'git',
['show', 'HEAD:docs/task.md'],
repoRoot,
).stdout;
expect(committedTaskContent).toBe('v2\n');
const committedOtherContent = mustRun(
'git',
['show', 'HEAD:notes/other.md'],
repoRoot,
).stdout;
expect(committedOtherContent).toBe('other v1\n');
const statusResult = mustRun('git', ['status', '--short'], repoRoot);
expect(statusResult.stdout).toContain('M notes/other.md');
expect(statusResult.stdout).not.toContain('docs/task.md');
});
});