mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-11 08:24:57 +03:00
fix(verify-snapshots): support case fixture setup and workDir cwd
Two harness gaps that masked real issues and leaked stray files: 1. Case-level `setup: "fixture:<name>"` was ignored — runner.mjs handled it, verify-snapshots did not. skd-edit/add-drilldown silently failed with "File not found: Template.xml" because the fixture never reached workDir. Added Step 0 fixture copy mirroring runner.mjs behavior. 2. `skillConfig.cwd === "workDir"` was ignored — main skill always ran with cwd=REPO_ROOT. mxl-compile cases pass relative -OutputPath "Template.xml", which landed in the repo root on every run. Plumb cwd through execSkill and set mainCwd from skillConfig.cwd. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -60,17 +60,17 @@ function resolveScript(relPath, runtime) {
|
||||
return full;
|
||||
}
|
||||
|
||||
function execSkill(runtime, scriptRelPath, args, timeout = 60_000) {
|
||||
function execSkill(runtime, scriptRelPath, args, timeout = 60_000, cwd = REPO_ROOT) {
|
||||
const scriptPath = resolveScript(scriptRelPath, runtime);
|
||||
if (runtime === 'python') {
|
||||
return execFileSync(process.env.PYTHON || 'python', [scriptPath, ...args], {
|
||||
encoding: 'utf8', timeout, stdio: ['pipe', 'pipe', 'pipe'], cwd: REPO_ROOT,
|
||||
encoding: 'utf8', timeout, stdio: ['pipe', 'pipe', 'pipe'], cwd,
|
||||
});
|
||||
}
|
||||
return execFileSync('powershell.exe', [
|
||||
'-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass',
|
||||
'-File', scriptPath, ...args
|
||||
], { encoding: 'utf8', timeout, stdio: ['pipe', 'pipe', 'pipe'], cwd: REPO_ROOT });
|
||||
], { encoding: 'utf8', timeout, stdio: ['pipe', 'pipe', 'pipe'], cwd });
|
||||
}
|
||||
|
||||
// ─── Dependency resolution ──────────────────────────────────────────────────
|
||||
@@ -363,6 +363,21 @@ async function verifyCase(skillName, caseName, skillConfig, caseData, opts) {
|
||||
const configDir = (setupType === 'empty-config' || isCfInit) ? workDir : null;
|
||||
|
||||
try {
|
||||
// ── Step 0: Case-level fixture copy (runner.mjs compatibility) ──
|
||||
// A case may declare `"setup": "fixture:<name>"` pointing to
|
||||
// tests/skills/cases/<skill>/fixtures/<name> — copy its contents into workDir
|
||||
// so the skill script finds them at the expected relative path.
|
||||
if (typeof caseData.setup === 'string' && caseData.setup.startsWith('fixture:')) {
|
||||
const fixtureName = caseData.setup.slice('fixture:'.length);
|
||||
const fixturePath = join(CASES, skillName, 'fixtures', fixtureName);
|
||||
if (!existsSync(fixturePath)) {
|
||||
result.errors.push(`Fixture not found: ${fixturePath}`);
|
||||
return result;
|
||||
}
|
||||
cpSync(fixturePath, workDir, { recursive: true });
|
||||
log(`fixture: ${fixtureName}`, true);
|
||||
}
|
||||
|
||||
// ── Step 1: Setup (cf-init for empty-config, nothing for 'none') ──
|
||||
// Skip setup for cf-init skill — the test itself creates the config
|
||||
if (configDir && setupType === 'empty-config' && !CONFIG_INIT_SKILLS.has(skillName)) {
|
||||
@@ -468,7 +483,8 @@ async function verifyCase(skillName, caseName, skillConfig, caseData, opts) {
|
||||
|
||||
try {
|
||||
const { args } = buildSkillArgs(skillConfig, caseData, workDir, inputFile, opts.runtime);
|
||||
const output = execSkill(opts.runtime, skillConfig.script, args);
|
||||
const mainCwd = skillConfig.cwd === 'workDir' ? workDir : REPO_ROOT;
|
||||
const output = execSkill(opts.runtime, skillConfig.script, args, 60_000, mainCwd);
|
||||
const lastLine = output.trim().split('\n').pop();
|
||||
if (caseData.expectError) {
|
||||
log(skillName, false, 'expected non-zero exit but got success');
|
||||
|
||||
Reference in New Issue
Block a user