import { CollectingTrace, TestTraceable } from './test_utils'; import { LogLevel, LogMetricTrace, LogMetricTraceable, Metric, MetricsTrace, MetricValueTag, type MetricValue, } from '../lib/index'; describe('trace/trace (traceables + LogMetricTrace)', () => { beforeEach(() => { jest.useFakeTimers(); jest.setSystemTime(new Date('2020-01-01T00:00:00.000Z')); }); afterEach(() => { jest.useRealTimers(); }); test('LogMetricTrace routes metrics to MetricsTrace', () => { const emitted: MetricValue[] = []; const metrics = new MetricsTrace((vals: MetricValue[]) => emitted.push(...vals)); const logs = new CollectingTrace(); const t = new LogMetricTrace(logs, metrics); const m = Metric.fromName('x'); const scoped = t.traceScope(m); jest.setSystemTime(new Date('2020-01-01T00:00:00.010Z')); scoped.trace(m); expect(emitted).toEqual( expect.arrayContaining([ expect.objectContaining({ _tag: MetricValueTag, name: 'x.count', value: 1 }), expect.objectContaining({ _tag: MetricValueTag, name: 'x.time', value: 10 }), ]), ); }); test('LogMetricTrace routes non-metrics to LogTrace', () => { const metrics = new MetricsTrace(() => undefined); const logs = new CollectingTrace(); const t = new LogMetricTrace(logs, metrics); t.traceScope(LogLevel.INFO).trace('hello'); const flattened = logs.events.flatMap((e) => e); expect(flattened).toEqual(expect.arrayContaining([LogLevel.INFO, 'hello'])); }); test('LogMetricTraceable embeds emitted metrics into log trace', () => { const logs = new CollectingTrace(); const t = TestTraceable.of('x', logs); const withMetrics = LogMetricTraceable.ofLogTraceable(t); const metric = Metric.fromName('m'); withMetrics.trace.trace(metric.count.withValue(1)); const flattened = logs.events.flatMap((e) => e.map((x) => (typeof x === 'function' ? x() : x))); expect(flattened.some((x) => typeof x === 'string' && x.includes(''))).toBe(true); }); });