Single file, no transport, writes one JSON line per call to stdout. Child loggers inherit parent meta so scenarios can bind room/game context once and forget about it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
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);
|
|
});
|
|
});
|