144 lines
3.9 KiB
TypeScript
144 lines
3.9 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { normalizePieceConfig, mergeProviderOptions } from '../infra/config/loaders/pieceParser.js';
|
|
|
|
describe('normalizePieceConfig provider_options', () => {
|
|
it('piece-level global を movement に継承し、movement 側で上書きできる', () => {
|
|
const raw = {
|
|
name: 'provider-options',
|
|
piece_config: {
|
|
provider_options: {
|
|
codex: { network_access: true },
|
|
opencode: { network_access: false },
|
|
},
|
|
},
|
|
movements: [
|
|
{
|
|
name: 'codex-default',
|
|
provider: 'codex',
|
|
instruction: '{task}',
|
|
},
|
|
{
|
|
name: 'codex-override',
|
|
provider: 'codex',
|
|
provider_options: {
|
|
codex: { network_access: false },
|
|
},
|
|
instruction: '{task}',
|
|
},
|
|
],
|
|
};
|
|
|
|
const config = normalizePieceConfig(raw, process.cwd());
|
|
|
|
expect(config.providerOptions).toEqual({
|
|
codex: { networkAccess: true },
|
|
opencode: { networkAccess: false },
|
|
});
|
|
expect(config.movements[0]?.providerOptions).toEqual({
|
|
codex: { networkAccess: true },
|
|
opencode: { networkAccess: false },
|
|
});
|
|
expect(config.movements[1]?.providerOptions).toEqual({
|
|
codex: { networkAccess: false },
|
|
opencode: { networkAccess: false },
|
|
});
|
|
});
|
|
|
|
it('claude sandbox を piece-level で設定し movement で上書きできる', () => {
|
|
const raw = {
|
|
name: 'claude-sandbox',
|
|
piece_config: {
|
|
provider_options: {
|
|
claude: {
|
|
sandbox: { allow_unsandboxed_commands: true },
|
|
},
|
|
},
|
|
},
|
|
movements: [
|
|
{
|
|
name: 'inherit',
|
|
instruction: '{task}',
|
|
},
|
|
{
|
|
name: 'override',
|
|
provider_options: {
|
|
claude: {
|
|
sandbox: {
|
|
allow_unsandboxed_commands: false,
|
|
excluded_commands: ['./gradlew'],
|
|
},
|
|
},
|
|
},
|
|
instruction: '{task}',
|
|
},
|
|
],
|
|
};
|
|
|
|
const config = normalizePieceConfig(raw, process.cwd());
|
|
|
|
expect(config.providerOptions).toEqual({
|
|
claude: { sandbox: { allowUnsandboxedCommands: true } },
|
|
});
|
|
expect(config.movements[0]?.providerOptions).toEqual({
|
|
claude: { sandbox: { allowUnsandboxedCommands: true } },
|
|
});
|
|
expect(config.movements[1]?.providerOptions).toEqual({
|
|
claude: {
|
|
sandbox: {
|
|
allowUnsandboxedCommands: false,
|
|
excludedCommands: ['./gradlew'],
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
it('piece-level runtime.prepare を正規化し重複を除去する', () => {
|
|
const raw = {
|
|
name: 'runtime-prepare',
|
|
piece_config: {
|
|
runtime: {
|
|
prepare: ['gradle', 'node', 'gradle'],
|
|
},
|
|
},
|
|
movements: [
|
|
{
|
|
name: 'implement',
|
|
instruction: '{task}',
|
|
},
|
|
],
|
|
};
|
|
|
|
const config = normalizePieceConfig(raw, process.cwd());
|
|
|
|
expect(config.runtime).toEqual({
|
|
prepare: ['gradle', 'node'],
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('mergeProviderOptions', () => {
|
|
it('複数層を正しくマージする(後の層が優先)', () => {
|
|
const global = {
|
|
claude: { sandbox: { allowUnsandboxedCommands: false, excludedCommands: ['./gradlew'] } },
|
|
codex: { networkAccess: true },
|
|
};
|
|
const local = {
|
|
claude: { sandbox: { allowUnsandboxedCommands: true } },
|
|
};
|
|
const step = {
|
|
codex: { networkAccess: false },
|
|
};
|
|
|
|
const result = mergeProviderOptions(global, local, step);
|
|
|
|
expect(result).toEqual({
|
|
claude: { sandbox: { allowUnsandboxedCommands: true, excludedCommands: ['./gradlew'] } },
|
|
codex: { networkAccess: false },
|
|
});
|
|
});
|
|
|
|
it('すべて undefined なら undefined を返す', () => {
|
|
expect(mergeProviderOptions(undefined, undefined, undefined)).toBeUndefined();
|
|
});
|
|
});
|