import { resolveInputHint } from './metric-input-hint' import { MetricRendererRegistry } from './metric-renderer-registry' describe('resolveInputHint (client copy)', () => { it('meta 없음 → number 폴백', () => { expect(resolveInputHint(null)).toEqual({ widget: 'number', readonly: false }) expect(resolveInputHint({ collectType: 'AUTO' })).toEqual({ widget: 'number', readonly: true }) }) it('rating 기본값(max 5, step 1)', () => { expect(resolveInputHint({ meta: { input: { widget: 'rating' } } })).toEqual({ widget: 'rating', max: 5, step: 1, readonly: false }) }) it('readonly 명시 false 는 AUTO 라도 존중', () => { expect(resolveInputHint({ collectType: 'AUTO', meta: { input: { widget: 'number', readonly: false } } }).readonly).toBe( false ) }) }) describe('MetricRendererRegistry', () => { const dummy: any = () => null beforeEach(() => MetricRendererRegistry.clear()) it('매칭 없으면 undefined (→ 제네릭)', () => { expect(MetricRendererRegistry.resolve({ meta: {} } as any)).toBeUndefined() }) it('predicate 매칭 시 렌더러 반환, 먼저 등록된 것 우선', () => { const r1: any = () => 'r1' const r2: any = () => 'r2' MetricRendererRegistry.register((m: any) => m.name === 'X', r1) MetricRendererRegistry.register((m: any) => m.name === 'X', r2) expect(MetricRendererRegistry.resolve({ name: 'X' } as any)).toBe(r1) expect(MetricRendererRegistry.resolve({ name: 'Y' } as any)).toBeUndefined() }) it('predicate 예외는 매칭 실패로 처리(다음으로 진행)', () => { MetricRendererRegistry.register(() => { throw new Error('boom') }, dummy) const ok: any = () => 'ok' MetricRendererRegistry.register((m: any) => m.name === 'Z', ok) expect(MetricRendererRegistry.resolve({ name: 'Z' } as any)).toBe(ok) }) })