Files
alighasami 3d5eaf9445
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
first commit
2026-03-17 16:22:57 +03:30

183 lines
5.4 KiB
TypeScript

import { parseEvaluationArgs, type EvaluationSuite } from '../cli/argument-parser';
describe('argument-parser', () => {
describe('suite options', () => {
it('accepts all valid suite options', () => {
const validSuites: EvaluationSuite[] = [
'llm-judge',
'pairwise',
'programmatic',
'similarity',
];
for (const suite of validSuites) {
const args = parseEvaluationArgs(['--suite', suite]);
expect(args.suite).toBe(suite);
}
});
});
it('parses numeric flags like --max-examples and --concurrency', () => {
const args = parseEvaluationArgs([
'--suite',
'pairwise',
'--backend',
'langsmith',
'--max-examples',
'5',
'--concurrency',
'3',
]);
expect(args.maxExamples).toBe(5);
expect(args.concurrency).toBe(3);
});
it('supports inline --max-examples= syntax', () => {
const args = parseEvaluationArgs(['--max-examples=7']);
expect(args.maxExamples).toBe(7);
});
it('parses filters for pairwise suite', () => {
const args = parseEvaluationArgs([
'--suite',
'pairwise',
'--backend',
'langsmith',
'--filter',
'do:Slack',
'--filter',
'technique:content_generation',
]);
expect(args.filters).toEqual({
doSearch: 'Slack',
technique: 'content_generation',
});
});
it('accepts prompt values that start with "-"', () => {
const args = parseEvaluationArgs(['--prompt', '-starts-with-dash']);
expect(args.prompt).toBe('-starts-with-dash');
});
it('rejects conflicting backend/local when --langsmith is set', () => {
expect(() => parseEvaluationArgs(['--langsmith', '--backend', 'local'])).toThrow(
'Cannot combine `--langsmith` with `--backend local`',
);
});
it('treats --langsmith as backend=langsmith', () => {
const args = parseEvaluationArgs(['--langsmith']);
expect(args.backend).toBe('langsmith');
});
it('rejects do/dont filters for non-pairwise suite', () => {
expect(() => parseEvaluationArgs(['--suite', 'llm-judge', '--filter', 'do:Slack'])).toThrow(
'only supported for `--suite pairwise`',
);
});
it('rejects malformed filters', () => {
expect(() =>
parseEvaluationArgs(['--suite', 'pairwise', '--backend', 'langsmith', '--filter', 'nope']),
).toThrow('Invalid `--filter` format');
});
describe('--webhook-url', () => {
it('parses valid HTTPS webhook URL', () => {
const args = parseEvaluationArgs(['--webhook-url', 'https://example.com/webhook']);
expect(args.webhookUrl).toBe('https://example.com/webhook');
});
it('parses webhook URL with inline = syntax', () => {
const args = parseEvaluationArgs(['--webhook-url=https://api.example.com/hook']);
expect(args.webhookUrl).toBe('https://api.example.com/hook');
});
it('rejects invalid URL format', () => {
expect(() => parseEvaluationArgs(['--webhook-url', 'not-a-url'])).toThrow();
});
it('rejects non-URL strings', () => {
expect(() => parseEvaluationArgs(['--webhook-url', 'just-some-text'])).toThrow();
});
it('allows webhook URL to be undefined when not provided', () => {
const args = parseEvaluationArgs([]);
expect(args.webhookUrl).toBeUndefined();
});
it('parses webhook URL with path and query params', () => {
const args = parseEvaluationArgs([
'--webhook-url',
'https://hooks.example.com/api/v1/notify?token=abc123',
]);
expect(args.webhookUrl).toBe('https://hooks.example.com/api/v1/notify?token=abc123');
});
});
it('accepts binary-checks suite', () => {
const args = parseEvaluationArgs(['--suite', 'binary-checks']);
expect(args.suite).toBe('binary-checks');
});
it('parses --checks flag as comma-separated list', () => {
const args = parseEvaluationArgs([
'--suite',
'binary-checks',
'--checks',
'has_nodes,has_trigger,all_nodes_connected',
]);
expect(args.checks).toEqual(['has_nodes', 'has_trigger', 'all_nodes_connected']);
});
it('trims whitespace in --checks values', () => {
const args = parseEvaluationArgs([
'--suite',
'binary-checks',
'--checks',
' has_nodes , has_trigger ',
]);
expect(args.checks).toEqual(['has_nodes', 'has_trigger']);
});
it('throws when --checks is used with non-binary-checks suite', () => {
expect(() => parseEvaluationArgs(['--suite', 'llm-judge', '--checks', 'has_nodes'])).toThrow(
'`--checks` is only supported for `--suite binary-checks`',
);
});
describe('--webhook-secret', () => {
it('parses valid webhook secret', () => {
const args = parseEvaluationArgs(['--webhook-secret', 'my-secure-secret-key-1234567890']);
expect(args.webhookSecret).toBe('my-secure-secret-key-1234567890');
});
it('parses webhook secret with inline = syntax', () => {
const args = parseEvaluationArgs(['--webhook-secret=another-secret-key-12345678']);
expect(args.webhookSecret).toBe('another-secret-key-12345678');
});
it('rejects secret shorter than 16 characters', () => {
expect(() => parseEvaluationArgs(['--webhook-secret', 'short'])).toThrow();
});
it('allows webhook secret to be undefined when not provided', () => {
const args = parseEvaluationArgs([]);
expect(args.webhookSecret).toBeUndefined();
});
it('can be combined with webhook URL', () => {
const args = parseEvaluationArgs([
'--webhook-url',
'https://example.com/webhook',
'--webhook-secret',
'my-secure-secret-key-1234567890',
]);
expect(args.webhookUrl).toBe('https://example.com/webhook');
expect(args.webhookSecret).toBe('my-secure-secret-key-1234567890');
});
});
});