mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-17 23:28:04 +02:00
89 lines
3.3 KiB
JavaScript
89 lines
3.3 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('assert');
|
|
const { spawnSync } = require('child_process');
|
|
const { materializeManagedHooks } = require('../../scripts/lib/install/claude-settings');
|
|
|
|
function config(command) {
|
|
return {
|
|
hooks: {
|
|
Stop: [{ id: 'ecc:array', hooks: [{ type: 'command', command }] }],
|
|
},
|
|
};
|
|
}
|
|
|
|
function materialize(command, root = '/opt/ecc') {
|
|
return materializeManagedHooks(config(command), root).Stop[0].hooks[0].command;
|
|
}
|
|
|
|
const tests = [
|
|
['materializes every array command without changing the source', () => {
|
|
const source = config([
|
|
'node -e "var e=process.env.CLAUDE_PLUGIN_ROOT;console.log(e)"',
|
|
'node -e "var e=process.env.CLAUDE_PLUGIN_ROOT;console.log(e)"',
|
|
'${CLAUDE_PLUGIN_ROOT}/scripts/start.js',
|
|
'--unchanged',
|
|
]);
|
|
const before = JSON.parse(JSON.stringify(source));
|
|
const command = materializeManagedHooks(source, '/opt/ecc').Stop[0].hooks[0].command;
|
|
assert.deepStrictEqual(source, before);
|
|
assert.notStrictEqual(command, source.hooks.Stop[0].hooks[0].command);
|
|
assert.ok(command.slice(0, 2).every(value => !value.includes('process.env.CLAUDE_PLUGIN_ROOT')));
|
|
assert.deepStrictEqual(command.slice(2), ['/opt/ecc/scripts/start.js', '--unchanged']);
|
|
}],
|
|
['array argv commands execute with the exact root in a clean process', () => {
|
|
const root = '/tmp/ECC space/\'"$`\\路径';
|
|
const command = materialize([
|
|
process.execPath,
|
|
'-e',
|
|
'var e=process.env.CLAUDE_PLUGIN_ROOT;process.stdout.write(e);',
|
|
], root);
|
|
const result = spawnSync(command[0], command.slice(1), {
|
|
env: {},
|
|
encoding: 'utf8',
|
|
timeout: 5000,
|
|
});
|
|
assert.ifError(result.error);
|
|
assert.strictEqual(result.status, 0, result.stderr);
|
|
assert.strictEqual(result.stdout, root);
|
|
}],
|
|
...[0, 1].map(index => [
|
|
`rejects an unresolved root read in array element ${index}`,
|
|
() => {
|
|
const command = ['echo first', 'echo second'];
|
|
command[index] = 'node -e "const root=process.env.CLAUDE_PLUGIN_ROOT"';
|
|
assert.throws(() => materialize(command), /Unable to resolve CLAUDE_PLUGIN_ROOT/);
|
|
},
|
|
]),
|
|
['rejects a remaining root read after resolving an array prologue', () => {
|
|
assert.throws(() => materialize([
|
|
'var e=process.env.CLAUDE_PLUGIN_ROOT;console.log(process.env.CLAUDE_PLUGIN_ROOT);',
|
|
]), /Unable to resolve CLAUDE_PLUGIN_ROOT/);
|
|
}],
|
|
['retains supported root assignments in array commands', () => {
|
|
const command = materialize([
|
|
'var e=process.env.CLAUDE_PLUGIN_ROOT;process.env.CLAUDE_PLUGIN_ROOT=e;',
|
|
]);
|
|
assert.ok(!command[0].includes('var e=process.env.CLAUDE_PLUGIN_ROOT;'));
|
|
assert.ok(command[0].includes('process.env.CLAUDE_PLUGIN_ROOT=e;'));
|
|
}],
|
|
['invalid arrays still fail command validation', () => {
|
|
for (const command of [[], ['node', null], ['node', 3], ['node', ' ']]) {
|
|
assert.throws(() => materialize(command), /invalid command/);
|
|
}
|
|
}],
|
|
];
|
|
|
|
let failed = 0;
|
|
for (const [name, run] of tests) {
|
|
try {
|
|
run();
|
|
console.log(` PASS ${name}`);
|
|
} catch (error) {
|
|
failed += 1;
|
|
console.error(` FAIL ${name}\n ${error.stack || error.message}`);
|
|
}
|
|
}
|
|
console.log(`\nResults: Passed: ${tests.length - failed}, Failed: ${failed}`);
|
|
process.exitCode = failed > 0 ? 1 : 0;
|