import { describe, expect, test } from 'claude-code/testing' import type { Complete } from './classify' import { resolveConfig } from './config' import { buildInjection } from './inject' import type { IndexEntry } from './retrieval' const entry = (id: string, fn: IndexEntry['function']): IndexEntry => ({ id, function: fn, emotion: 'neutral', mode: null, text: `句${id}` }) const indexes = { 'sao-asuna': [entry('a', 'comfort'), entry('b', 'comfort')], 'sao-suguha': [] as IndexEntry[], } const answer = (text: string): Complete => async () => ({ isAnswered: true, text }) const deps = (opts: Record, complete: Complete, calls = { n: 0 }) => ({ config: resolveConfig(opts), indexes, complete: async (r: Parameters[0]) => (calls.n++, complete(r)), now: () => 0, turn: 0, }) describe('buildInjection', () => { const on = { defaultCharacter: 'sao-asuna', intensity: '2' } test('分類成功時回傳同標籤的對白', async () => { const r = await buildInjection(deps(on, answer('comfort')), '測試失敗了') expect(r?.fn).toBe('comfort') expect(r?.text).toContain('句a') }) test('沒選角色或強度 0 不呼叫模型', async () => { const calls = { n: 0 } expect(await buildInjection(deps({ intensity: '2' }, answer('comfort'), calls), 'x')).toBeNull() expect(await buildInjection(deps({ ...on, intensity: '0' }, answer('comfort'), calls), 'x')).toBeNull() expect(calls.n).toBe(0) }) test('索引為空不呼叫模型', async () => { const calls = { n: 0 } expect(await buildInjection(deps({ defaultCharacter: 'sao-suguha', intensity: '2' }, answer('comfort'), calls), 'x')).toBeNull() expect(calls.n).toBe(0) }) test('分類失敗退回不注入,但仍回報耗時', async () => { const r = await buildInjection(deps(on, async () => ({ isAnswered: false })), 'x') expect(r).toEqual({ text: null, fn: null, ms: 0 }) }) test('該標籤沒有對白時不注入', async () => { const r = await buildInjection(deps(on, answer('greet')), 'x') expect(r?.fn).toBe('greet') expect(r?.text).toBeNull() }) })