import { describe, expect, test, jest } from '@jest/globals';
import { ArgumentParser } from '../../../../src/engine/execution/parsers/argument-parser.js';
import type { ConvertedPrompt } from '../../../../src/shared/types/index.js';
const createLogger = () => ({
info: jest.fn(),
error: jest.fn(),
warn: jest.fn(),
debug: jest.fn(),
});
describe('ArgumentParser schema enforcement', () => {
test('reports validation errors when schema validation fails', async () => {
const parser = new ArgumentParser(createLogger());
const promptData: ConvertedPrompt = {
id: 'test',
name: 'Test',
description: '',
category: 'general',
userMessageTemplate: 'Hello {{iterations}}',
arguments: [
{
name: 'iterations',
required: true,
type: 'number',
},
],
};
const result = await parser.parseArguments('', promptData, {});
expect(result.validationResults).toHaveLength(1);
expect(result.validationResults[0].valid).toBe(false);
expect(result.validationResults[0].errors?.[0]?.code).toBe('REQUIRED_ARGUMENT_MISSING');
});
});
describe('ArgumentParser multi-argument parsing', () => {
const createMultiArgPrompt = (): ConvertedPrompt => ({
id: 'multi-arg-test',
name: 'Multi Arg Test',
description: '',
category: 'general',
userMessageTemplate: '{{input}} {{data}} {{format}}',
arguments: [
{ name: 'input', required: false },
{ name: 'data', required: false },
{ name: 'format', required: false },
],
});
test('parses multiple arguments with equals delimiter', async () => {
const parser = new ArgumentParser(createLogger());
const result = await parser.parseArguments(
'input="value1" data="value2"',
createMultiArgPrompt(),
{}
);
expect(result.processedArgs.input).toBe('value1');
expect(result.processedArgs.data).toBe('value2');
});
test('parses multiple arguments with colon delimiter', async () => {
const parser = new ArgumentParser(createLogger());
const result = await parser.parseArguments(
'input:"value1" data:"value2"',
createMultiArgPrompt(),
{}
);
expect(result.processedArgs.input).toBe('value1');
expect(result.processedArgs.data).toBe('value2');
});
test('parses mixed delimiter syntax', async () => {
const parser = new ArgumentParser(createLogger());
const result = await parser.parseArguments(
'input="value1" format:"json"',
createMultiArgPrompt(),
{}
);
expect(result.processedArgs.input).toBe('value1');
expect(result.processedArgs.format).toBe('json');
});
test('parses three or more arguments', async () => {
const parser = new ArgumentParser(createLogger());
const result = await parser.parseArguments(
'input:"first" data:"second" format:"third"',
createMultiArgPrompt(),
{}
);
expect(result.processedArgs.input).toBe('first');
expect(result.processedArgs.data).toBe('second');
expect(result.processedArgs.format).toBe('third');
});
test('handles single-quoted values with colon delimiter', async () => {
const parser = new ArgumentParser(createLogger());
const result = await parser.parseArguments(
"input:'Quarterly metrics' data:'Sales report'",
createMultiArgPrompt(),
{}
);
expect(result.processedArgs.input).toBe('Quarterly metrics');
expect(result.processedArgs.data).toBe('Sales report');
});
test('handles values with special characters', async () => {
const parser = new ArgumentParser(createLogger());
const result = await parser.parseArguments(
'input:"/home/user/file.ts" data:"https://example.com?param=value"',
createMultiArgPrompt(),
{}
);
expect(result.processedArgs.input).toBe('/home/user/file.ts');
expect(result.processedArgs.data).toBe('https://example.com?param=value');
});
});
describe('ArgumentParser dashed argument names', () => {
const createDashedPrompt = (): ConvertedPrompt => ({
id: 'dashed-test',
name: 'Dashed Test',
description: '',
category: 'general',
userMessageTemplate: '{{output-format}} {{file-path}}',
arguments: [
{ name: 'output-format', required: false },
{ name: 'file-path', required: false },
],
});
test('parses argument names with dashes', async () => {
const parser = new ArgumentParser(createLogger());
const result = await parser.parseArguments(
'output-format:"json" file-path:"/src/main.ts"',
createDashedPrompt(),
{}
);
expect(result.processedArgs['output-format']).toBe('json');
expect(result.processedArgs['file-path']).toBe('/src/main.ts');
});
test('parses dashed names with equals delimiter', async () => {
const parser = new ArgumentParser(createLogger());
const result = await parser.parseArguments('output-format="xml"', createDashedPrompt(), {});
expect(result.processedArgs['output-format']).toBe('xml');
});
});