| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- import { describe, expect, it } from 'vitest'
- import {
- MOCK_LLM_CLI_USAGE,
- parseMockLlmCliArgs,
- } from '../src/cli.ts'
- describe('mock LLM server CLI parser', () => {
- it('returns help without requiring a sequence', () => {
- expect(parseMockLlmCliArgs(['--help'])).toEqual({ kind: 'help' })
- expect(MOCK_LLM_CLI_USAGE).toContain('--sequence')
- })
- it('parses every request and listener option', () => {
- expect(parseMockLlmCliArgs([
- '--sequence', 'connection_refused,partial_disconnect,success',
- '--host', 'localhost',
- '--port', '9010',
- '--api-key', 'mock-key',
- '--listen-delay-ms', '100',
- '--repeat-last',
- '--success-text', 'done',
- '--partial-text', 'half',
- '--reasoning-text', 'think',
- '--chunk-size', '2',
- '--chunk-delay-ms', '3',
- '--disconnect-delay-ms', '4',
- '--retry-after-ms', '5000',
- '--request-id', 'request-1',
- '--tool-name', 'lookup',
- '--tool-arguments', '{"id":1}',
- ])).toEqual({
- kind: 'run',
- config: {
- startsUnavailable: true,
- listenDelayMs: 100,
- server: {
- sequence: ['partial_disconnect', 'success'],
- host: 'localhost',
- port: 9010,
- apiKey: 'mock-key',
- repeatLast: true,
- successText: 'done',
- partialText: 'half',
- reasoningText: 'think',
- chunkSize: 2,
- chunkDelayMs: 3,
- disconnectDelayMs: 4,
- retryAfterMs: 5000,
- requestId: 'request-1',
- toolName: 'lookup',
- toolArguments: '{"id":1}',
- },
- },
- })
- })
- it('uses standalone defaults for an ordinary sequence', () => {
- expect(parseMockLlmCliArgs(['--sequence', 'success'])).toEqual({
- kind: 'run',
- config: {
- startsUnavailable: false,
- listenDelayMs: 0,
- server: {
- sequence: ['success'],
- port: 8000,
- repeatLast: false,
- },
- },
- })
- })
- it('uses the default unavailable interval', () => {
- const result = parseMockLlmCliArgs(['--sequence', 'connection_refused,success', '--port', '8001'])
- expect(result).toMatchObject({
- kind: 'run',
- config: { startsUnavailable: true, listenDelayMs: 750 },
- })
- })
- it('parses a reproducible weighted random profile', () => {
- expect(parseMockLlmCliArgs([
- '--sequence', 'random',
- '--repeat-last',
- '--seed', '42',
- '--random-weights', 'success=8,partial_disconnect=2',
- ])).toEqual({
- kind: 'run',
- config: {
- startsUnavailable: false,
- listenDelayMs: 0,
- server: {
- sequence: ['random'],
- port: 8000,
- repeatLast: true,
- randomSeed: 42,
- randomWeights: { success: 8, partial_disconnect: 2 },
- },
- },
- })
- })
- it.each([
- [[], /--sequence is required/],
- // Tokenizer-level failures carry node:util parseArgs's own messages.
- [['--wat'], /Unknown option '--wat'/],
- [['--wat', 'x'], /Unknown option '--wat'/],
- [['--port'], /Option '--port <value>' argument missing/],
- [['--sequence', 'success', 'stray'], /Unexpected argument 'stray'/],
- [['--port', 'NaN', '--sequence', 'success'], /finite number/],
- [['--sequence', 'success,'], /non-empty/],
- [['--sequence', 'success,connection_refused'], /only as the first/],
- [['--sequence', 'connection_refused'], /must be followed/],
- [['--sequence', 'unknown'], /unknown behavior/],
- [['--sequence', 'connection_refused,success', '--port', '0'], /nonzero/],
- [['--sequence', 'success', '--listen-delay-ms', '5'], /requires connection_refused/],
- // `=` syntax: a space-separated leading-dash value is a tokenizer error, not a bounds probe.
- [['--sequence', 'connection_refused,success', '--listen-delay-ms=-1'], /integer between 0 and 2147483647/],
- [['--sequence', 'connection_refused,success', '--listen-delay-ms', '1.5'], /integer between 0 and 2147483647/],
- [['--sequence', 'connection_refused,success', '--listen-delay-ms', '2147483648'], /integer between 0 and 2147483647/],
- [['--sequence', 'success', '--seed', '1'], /require random/],
- [['--sequence', 'random', '--random-weights', 'success'], /expects behavior=weight/],
- [['--sequence', 'random', '--random-weights', 'random=1'], /concrete behavior/],
- [['--sequence', 'random', '--random-weights', 'success=1,success=2'], /duplicate/],
- [['--sequence', 'random', '--random-weights', 'success=nope'], /finite number/],
- ])('rejects invalid argv %#', (argv, expected) => {
- expect(() => parseMockLlmCliArgs(argv)).toThrow(expected)
- })
- })
|