// tools/router-embedding.test.mjs — TDD for Phase 2 Task 12 (spec §4.3) import { describe, it, expect } from 'vitest'; import { shouldEmbed, encodeBase64, decodeBase64 } from './router-embedding.mjs'; describe('shouldEmbed (§4.3 — skip exempt task types)', () => { it('skips conversation', () => expect(shouldEmbed('conversation')).toBe(false)); it('skips micro', () => expect(shouldEmbed('micro')).toBe(false)); it('skips manual_override', () => expect(shouldEmbed('manual_override')).toBe(false)); it('embeds feature', () => expect(shouldEmbed('feature')).toBe(true)); it('embeds bugfix', () => expect(shouldEmbed('bugfix')).toBe(true)); it('embeds unknown task_type defensively', () => expect(shouldEmbed('weird')).toBe(true)); }); describe('base64 roundtrip (Float32 storage, ~2050 chars per spec)', () => { it('roundtrips a small float32 array', () => { const v = new Float32Array([0.1, -0.5, 0.9]); expect(Array.from(decodeBase64(encodeBase64(v)))).toEqual(Array.from(v)); }); it('roundtrips empty', () => { const v = new Float32Array(0); expect(decodeBase64(encodeBase64(v)).length).toBe(0); }); it('roundtrips 384-dim (MiniLM-L6-v2 output size)', () => { const v = new Float32Array(384); for (let i = 0; i < 384; i++) v[i] = Math.sin(i); expect(Array.from(decodeBase64(encodeBase64(v)))).toEqual(Array.from(v)); }); it('encodes 384-dim to base64 string in ~2050 char range (spec §4.3)', () => { const v = new Float32Array(384); const b64 = encodeBase64(v); expect(typeof b64).toBe('string'); // 384 * 4 bytes = 1536 bytes → base64 = ceil(1536/3) * 4 = 2048 chars expect(b64.length).toBeGreaterThanOrEqual(2040); expect(b64.length).toBeLessThanOrEqual(2060); }); });