import { describe, it, expect, beforeEach } from 'vitest'; import { createLogger } from '../core/logger'; describe('logger', () => { let writes: string[]; let write: (s: string) => boolean; beforeEach(() => { writes = []; write = (s: string) => { writes.push(s); return true; }; }); it('emits a JSON line per call with level and msg', () => { const log = createLogger({ runId: 'r1', write }); log.info('hello'); expect(writes).toHaveLength(1); const parsed = JSON.parse(writes[0]); expect(parsed.level).toBe('info'); expect(parsed.msg).toBe('hello'); expect(parsed.runId).toBe('r1'); expect(parsed.timestamp).toBeTypeOf('string'); }); it('merges meta into the log line', () => { const log = createLogger({ runId: 'r1', write }); log.warn('slow', { turnMs: 3000 }); const parsed = JSON.parse(writes[0]); expect(parsed.turnMs).toBe(3000); expect(parsed.level).toBe('warn'); }); it('child logger inherits parent meta', () => { const log = createLogger({ runId: 'r1', write }); const roomLog = log.child({ room: 'room-1' }); roomLog.info('game_start'); const parsed = JSON.parse(writes[0]); expect(parsed.room).toBe('room-1'); expect(parsed.runId).toBe('r1'); }); it('respects minimum level', () => { const log = createLogger({ runId: 'r1', write, minLevel: 'warn' }); log.debug('nope'); log.info('nope'); log.warn('yes'); log.error('yes'); expect(writes).toHaveLength(2); }); });