补充任务提交脚本测试覆盖
This commit is contained in:
@@ -69,3 +69,10 @@ node scripts/commit-task.mjs \
|
|||||||
1. 用户明确表示任务完成,或直接要求提交时,优先使用这条工作流。
|
1. 用户明确表示任务完成,或直接要求提交时,优先使用这条工作流。
|
||||||
2. 若当前任务文件边界清晰,则直接提交。
|
2. 若当前任务文件边界清晰,则直接提交。
|
||||||
3. 若边界不清晰,则先停下并说明风险,不强行提交。
|
3. 若边界不清晰,则先停下并说明风险,不强行提交。
|
||||||
|
|
||||||
|
## 7. 验证
|
||||||
|
|
||||||
|
当前已补:
|
||||||
|
|
||||||
|
1. `scripts/commit-task.test.ts`
|
||||||
|
2. 覆盖“只提交指定文件,保留未指定改动在工作区”的核心行为
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
import { spawnSync } from 'node:child_process';
|
import { spawnSync } from 'node:child_process';
|
||||||
|
|
||||||
|
const repoRoot = process.env.GENARRATIVE_COMMIT_REPO_ROOT?.trim() || '/home/Genarrative';
|
||||||
|
|
||||||
function fail(message) {
|
function fail(message) {
|
||||||
console.error(`[commit-task] ${message}`);
|
console.error(`[commit-task] ${message}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
@@ -9,7 +11,7 @@ function fail(message) {
|
|||||||
|
|
||||||
function runGit(args, options = {}) {
|
function runGit(args, options = {}) {
|
||||||
const result = spawnSync('git', args, {
|
const result = spawnSync('git', args, {
|
||||||
cwd: '/home/Genarrative',
|
cwd: repoRoot,
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
stdio: ['inherit', 'pipe', 'pipe'],
|
stdio: ['inherit', 'pipe', 'pipe'],
|
||||||
...options,
|
...options,
|
||||||
@@ -53,4 +55,3 @@ if (!stagedOutput) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runGit(['commit', '-m', message], { stdio: 'inherit' });
|
runGit(['commit', '-m', message], { stdio: 'inherit' });
|
||||||
|
|
||||||
|
|||||||
87
scripts/commit-task.test.ts
Normal file
87
scripts/commit-task.test.ts
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
||||||
|
import { tmpdir } from 'node:os';
|
||||||
|
import { dirname, 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');
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user