Files
tea-sdlc/test/helpers/temp-repo.js
T
jiantw83andClaude Opus 5 28dec83498 test(腳本契約): 以子行程與 stub server 驗證契約與四層前置檢查
測試一律以子行程執行腳本、比對 stdout 的單行 JSON 與 exit code,因為那正是
七個平台共用的實際呼叫方式,不會因內部重構而破碎。

Gitea 以本機 stub server 替身並錄下每一筆請求,藉此斷言「腳本到底發了哪些
請求」——包含 --dry-run 不得發出任何請求、前一層檢查沒過就不再往下打、
寫入權探針不得挾帶任何要寫入的欄位。git 則在 .tmp/ 下的臨時 repo 跑真實
指令,比 mock 可信且成本低。

lib-exports.test.js 是唯一直接 import lib 的例外:冪等查重與 git 執行點在
CLI 邊界上還沒有消費者,檔頭已註明等 #4 與 #10 落地後即可縮小或移除。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 04:26:51 +00:00

32 lines
1.1 KiB
JavaScript

/**
* 在 .tmp/ 底下開一個真的 git repo。
* git 操作不做 mock:在臨時 repo 上跑真的 git 比假的 git 可信,成本也低。
*/
import { execFileSync } from 'node:child_process';
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
import { join } from 'node:path';
import { tmpRoot } from './run-script.js';
/**
* @returns {{dir: string, cleanup: Function}} dir 為已有一顆 commit 的 git repo
*/
export function makeTempRepo() {
mkdirSync(tmpRoot, { recursive: true });
const dir = mkdtempSync(join(tmpRoot, 'repo-'));
const git = (...args) =>
execFileSync('git', args, {
cwd: dir,
encoding: 'utf8',
env: { ...process.env, GIT_CONFIG_GLOBAL: '/dev/null', GIT_CONFIG_SYSTEM: '/dev/null' },
});
git('init', '-q', '-b', 'master');
git('config', 'user.name', 'tester');
git('config', 'user.email', 'tester@example.com');
writeFileSync(join(dir, 'README.md'), '# temp\n');
git('add', '-A');
git('commit', '-qm', 'initial');
return { dir, cleanup: () => rmSync(dir, { recursive: true, force: true }) };
}