import { LogLevel, LogTrace, type ILogger } from '../lib/index'; describe('trace/log/trace (LogTrace)', () => { beforeEach(() => { jest.useFakeTimers(); jest.setSystemTime(new Date('2020-01-01T00:00:00.000Z')); }); afterEach(() => { jest.useRealTimers(); }); test('uses defaultLevel when no explicit level', () => { const logger: ILogger = { log: jest.fn() }; const allowed = () => new Set([LogLevel.UNKNOWN, LogLevel.WARN]); const trace = new LogTrace(logger, [], LogLevel.WARN, allowed); trace.trace('hello'); expect(logger.log).toHaveBeenCalledTimes(1); const [level, ...rest] = (logger.log as jest.Mock).mock.calls[0]; expect(level).toBe(LogLevel.WARN); expect(rest.join(' ')).toContain('hello'); }); test('picks highest log level across traces', () => { const logger: ILogger = { log: jest.fn() }; const allowed = () => new Set([LogLevel.UNKNOWN, LogLevel.INFO, LogLevel.WARN, LogLevel.ERROR]); const trace = new LogTrace(logger, [], LogLevel.INFO, allowed); trace.traceScope(LogLevel.INFO).traceScope(LogLevel.ERROR).trace('boom'); const [level] = (logger.log as jest.Mock).mock.calls[0]; expect(level).toBe(LogLevel.ERROR); }); test('filters disallowed levels', () => { const logger: ILogger = { log: jest.fn() }; const allowed = () => new Set([LogLevel.UNKNOWN, LogLevel.INFO]); const trace = new LogTrace(logger, [], LogLevel.INFO, allowed); trace.traceScope(LogLevel.DEBUG).trace('nope'); expect(logger.log).not.toHaveBeenCalled(); }); test('formats Error objects in trace', () => { const logger: ILogger = { log: jest.fn() }; const allowed = () => new Set([LogLevel.UNKNOWN, LogLevel.ERROR]); const trace = new LogTrace(logger, [], LogLevel.INFO, allowed); trace.traceScope(LogLevel.ERROR).trace(new Error('boom')); const [_level, msg] = (logger.log as jest.Mock).mock.calls[0]; expect(msg).toContain('TracedException.Name = Error'); expect(msg).toContain('TracedException.Message = boom'); }); });