import { describe, it, expect } from 'vitest'; import { parseCommandSchema, parseCommandWithSchema, validateCommand, parseCommand, type CommandSchema, } from '../../src/utils/command'; describe('parseCommandSchema with inline-schema', () => { it('should parse schema with typed params', () => { const schema = parseCommandSchema('move '); expect(schema.name).toBe('move'); expect(schema.params).toHaveLength(2); expect(schema.params[0].name).toBe('from'); expect(schema.params[0].schema).toBeDefined(); expect(schema.params[1].name).toBe('to'); expect(schema.params[1].schema).toBeDefined(); }); it('should parse schema with typed options', () => { const schema = parseCommandSchema('move [--all: boolean] [--count: number]'); expect(schema.name).toBe('move'); expect(schema.options).toHaveLength(2); expect(schema.options[0].name).toBe('all'); expect(schema.options[0].schema).toBeDefined(); expect(schema.options[1].name).toBe('count'); expect(schema.options[1].schema).toBeDefined(); }); it('should parse schema with tuple type', () => { const schema = parseCommandSchema('place '); expect(schema.name).toBe('place'); expect(schema.params).toHaveLength(1); expect(schema.params[0].name).toBe('coords'); expect(schema.params[0].schema).toBeDefined(); }); it('should parse schema with array type', () => { const schema = parseCommandSchema('select '); expect(schema.name).toBe('select'); expect(schema.params).toHaveLength(1); expect(schema.params[0].name).toBe('ids'); expect(schema.params[0].schema).toBeDefined(); }); it('should parse schema with tuple array type', () => { const schema = parseCommandSchema('place '); expect(schema.name).toBe('place'); expect(schema.params).toHaveLength(1); expect(schema.params[0].name).toBe('coords'); expect(schema.params[0].schema).toBeDefined(); }); it('should parse schema with mixed types', () => { const schema = parseCommandSchema( 'move [--all: boolean] [--count: number]' ); expect(schema.name).toBe('move'); expect(schema.params).toHaveLength(2); expect(schema.options).toHaveLength(2); }); it('should parse schema with optional typed param', () => { const schema = parseCommandSchema('move [to: string]'); expect(schema.name).toBe('move'); expect(schema.params).toHaveLength(2); expect(schema.params[0].required).toBe(true); expect(schema.params[1].required).toBe(false); expect(schema.params[1].schema).toBeDefined(); }); it('should parse schema with optional typed option', () => { const schema = parseCommandSchema('move [--speed: number]'); expect(schema.name).toBe('move'); expect(schema.options).toHaveLength(1); expect(schema.options[0].required).toBe(false); expect(schema.options[0].schema).toBeDefined(); }); }); describe('parseCommandWithSchema', () => { it('should parse and validate command with tuple param', () => { const result = parseCommandWithSchema( 'move [1; 2] region1', 'move ' ); expect(result.valid).toBe(true); if (result.valid) { expect(result.command.params).toHaveLength(2); expect(result.command.params[0]).toEqual(['1', '2']); expect(result.command.params[1]).toBe('region1'); } }); it('should parse and validate command with boolean option', () => { const result = parseCommandWithSchema( 'move meeple1 region1 --all true', 'move [--all: boolean]' ); expect(result.valid).toBe(true); if (result.valid) { expect(result.command.options.all).toBe(true); } }); it('should parse and validate command with number option', () => { const result = parseCommandWithSchema( 'move meeple1 region1 --count 5', 'move [--count: number]' ); expect(result.valid).toBe(true); if (result.valid) { expect(result.command.options.count).toBe(5); } }); it('should fail validation with wrong command name', () => { const result = parseCommandWithSchema( 'jump meeple1 region1', 'move ' ); expect(result.valid).toBe(false); if (!result.valid) { expect(result.errors).toContainEqual( expect.stringContaining('命令名称不匹配') ); } }); it('should fail validation with missing required param', () => { const result = parseCommandWithSchema( 'move meeple1', 'move ' ); expect(result.valid).toBe(false); if (!result.valid) { expect(result.errors).toContainEqual( expect.stringContaining('参数不足') ); } }); it('should fail validation with missing required option', () => { const result = parseCommandWithSchema( 'move meeple1 region1', 'move [--force: boolean]' ); // 可选选项,应该通过验证 expect(result.valid).toBe(true); }); it('should parse complex command with typed params and options', () => { const result = parseCommandWithSchema( 'move [1; 2] region1 --all true --count 3', 'move [--all: boolean] [--count: number]' ); expect(result.valid).toBe(true); if (result.valid) { expect(result.command.params[0]).toEqual(['1', '2']); expect(result.command.params[1]).toBe('region1'); expect(result.command.options.all).toBe(true); expect(result.command.options.count).toBe(3); } }); it('should handle number parsing in tuple', () => { const result = parseCommandWithSchema( 'place [10; 20]', 'place ' ); expect(result.valid).toBe(true); if (result.valid) { expect(result.command.params[0]).toEqual([10, 20]); } }); it('should handle string array parsing', () => { const result = parseCommandWithSchema( 'select [alice; bob; charlie]', 'select ' ); expect(result.valid).toBe(true); if (result.valid) { expect(result.command.params[0]).toEqual(['alice', 'bob', 'charlie']); } }); it('should handle tuple array parsing', () => { const result = parseCommandWithSchema( 'place [[1; 2]; [3; 4]; [5; 6]]', 'place ' ); expect(result.valid).toBe(true); if (result.valid) { expect(result.command.params[0]).toEqual([[1, 2], [3, 4], [5, 6]]); } }); }); describe('validateCommand with schema types', () => { it('should validate command with typed params', () => { const schema = parseCommandSchema('move '); const command = parseCommand('move [1; 2] region1'); const result = validateCommand(command, schema); expect(result.valid).toBe(true); }); it('should validate command with typed options', () => { const schema = parseCommandSchema('move [--all: boolean]'); const command = parseCommand('move meeple1 region1 --all true'); const result = validateCommand(command, schema); expect(result.valid).toBe(true); }); it('should fail validation with insufficient params', () => { const schema = parseCommandSchema('move '); const command = parseCommand('move [1; 2]'); const result = validateCommand(command, schema); expect(result.valid).toBe(false); if (!result.valid) { expect(result.errors).toContainEqual( expect.stringContaining('参数不足') ); } }); });