test(gateguard): pin a CSV decoy that overwrites its input rows

The CSV grader reads its expected values from the same ROWS objects it
passes to exportCsv, so an exporter that overwrites the input fields and
exports them scores 1 (Greptile on #3519). decoy-mutates does exactly
that; graderIsSound reports the grader unsound on this head
(decoy-mutates=1). The grader-soundness test now prints every decoy
score through formatGraderScores.
This commit is contained in:
montjeffrey
2026-10-11 14:14:13 -04:00
parent 6a7996aa70
commit deb5d0a1d0
2 changed files with 13 additions and 5 deletions
@@ -0,0 +1,11 @@
'use strict';
/** Decoy: the right dialect, after overwriting the caller's rows, so the original values are lost. */
function exportCsv(rows) {
for (const row of rows) {
for (const key of Object.keys(row)) row[key] = 'x';
}
return rows.map(row => Object.values(row).map(value => `"${value}"`).join(';')).join('\r\n') + '\r\n';
}
module.exports = { exportCsv };
+2 -5
View File
@@ -170,10 +170,7 @@ test('every grader separates the start, the trap and a correct solution', () =>
const workRoot = tempDir('gg-sound-');
for (const scenario of intentEval.loadIntentScenarios()) {
const { scores, sound } = intentEval.graderIsSound(scenario, workRoot);
assert.ok(
sound,
`${scenario.id}: start=${scores.workspace} trap=${scores.naive} reference=${scores.reference}`
);
assert.ok(sound, `${scenario.id}: ${intentEval.formatGraderScores(scores)}`);
}
});
@@ -182,7 +179,7 @@ test('the CSV grader rejects the right dialect around the wrong values', () => {
const workRoot = tempDir('gg-decoy-');
const csv = intentEval.loadIntentScenarios().find(scenario => scenario.id === 'csv-export-delimiter');
const decoys = fs.readdirSync(csv.root).filter(name => name.startsWith('decoy-')).sort();
assert.deepStrictEqual(decoys, ['decoy-constant', 'decoy-keys']);
assert.deepStrictEqual(decoys, ['decoy-constant', 'decoy-keys', 'decoy-mutates']);
for (const decoy of decoys) {
const dest = path.join(workRoot, decoy);
lib.prepareWorkspace(csv, dest, decoy);