summaryrefslogtreecommitdiff
path: root/tst/metrics_trace.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'tst/metrics_trace.test.ts')
-rw-r--r--tst/metrics_trace.test.ts125
1 files changed, 125 insertions, 0 deletions
diff --git a/tst/metrics_trace.test.ts b/tst/metrics_trace.test.ts
new file mode 100644
index 0000000..23d5147
--- /dev/null
+++ b/tst/metrics_trace.test.ts
@@ -0,0 +1,125 @@
+import { Metric, MetricsTrace, MetricValueTag, isMetricsTraceSupplier, type MetricValue } from '../lib/index';
+
+describe('trace/metric/trace (MetricsTrace)', () => {
+ beforeEach(() => {
+ jest.useFakeTimers();
+ jest.setSystemTime(new Date('2020-01-01T00:00:00.000Z'));
+ });
+
+ afterEach(() => {
+ jest.useRealTimers();
+ });
+
+ test('isMetricsTraceSupplier accepts metrics and values', () => {
+ const m = Metric.fromName('m');
+ const v = m.count.withValue(1);
+
+ expect(isMetricsTraceSupplier(m)).toBe(true);
+ expect(isMetricsTraceSupplier(v)).toBe(true);
+ expect(isMetricsTraceSupplier([m, v])).toBe(true);
+ expect(isMetricsTraceSupplier('nope')).toBe(false);
+ expect(isMetricsTraceSupplier(undefined)).toBe(false);
+ });
+
+ test('traceScope + trace ends a metric and emits count/time', () => {
+ const emitted: MetricValue[] = [];
+ const consumer = (vals: MetricValue[]) => emitted.push(...vals);
+
+ const metric = Metric.fromName('A');
+ const t0 = new MetricsTrace(consumer).traceScope(metric);
+
+ jest.setSystemTime(new Date('2020-01-01T00:00:00.100Z'));
+ t0.trace(metric);
+
+ expect(emitted).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({ _tag: MetricValueTag, name: 'A.count', value: 1 }),
+ expect.objectContaining({ _tag: MetricValueTag, name: 'A.time', value: 100 }),
+ ]),
+ );
+ });
+
+ test('trace does not emit when given string/undefined', () => {
+ const emitted: MetricValue[] = [];
+ const consumer = (vals: MetricValue[]) => emitted.push(...vals);
+ const t = new MetricsTrace(consumer);
+
+ t.trace(undefined);
+ t.trace('hello');
+ expect(emitted).toEqual([]);
+ });
+
+ test('parent-based metric emits relative to parent start', () => {
+ const emitted: MetricValue[] = [];
+ const consumer = (vals: MetricValue[]) => emitted.push(...vals);
+
+ const parent = Metric.fromName('parent');
+ const child = parent.child('child');
+
+ const t0 = new MetricsTrace(consumer).traceScope(parent);
+
+ jest.setSystemTime(new Date('2020-01-01T00:00:00.050Z'));
+ const t1 = t0.trace(child);
+
+ expect(emitted).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({ name: 'parent.child.count', value: 1 }),
+ expect.objectContaining({ name: 'parent.child.time', value: 50 }),
+ ]),
+ );
+
+ // end parent normally
+ jest.setSystemTime(new Date('2020-01-01T00:00:00.080Z'));
+ t1.trace(parent);
+ expect(emitted).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({ name: 'parent.count', value: 1 }),
+ expect.objectContaining({ name: 'parent.time', value: 80 }),
+ ]),
+ );
+
+ // child should be considered completed already
+ const before = emitted.length;
+ jest.setSystemTime(new Date('2020-01-01T00:00:00.100Z'));
+ t1.trace(child);
+ expect(emitted.length).toBe(before);
+ });
+
+ test('nested scope can end parent metric via result child', () => {
+ const emitted: MetricValue[] = [];
+ const consumer = (vals: MetricValue[]) => emitted.push(...vals);
+
+ const result = Metric.fromName('job').asResult();
+
+ const root = new MetricsTrace(consumer).traceScope(result);
+
+ jest.setSystemTime(new Date('2020-01-01T00:00:00.100Z'));
+ const child = root.traceScope('child-scope');
+ const childAfterSuccess = child.trace(result.success);
+
+ expect(emitted).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({ name: 'job.success.count', value: 1 }),
+ expect.objectContaining({ name: 'job.success.time', value: 100 }),
+ ]),
+ );
+
+ const before = emitted.length;
+ jest.setSystemTime(new Date('2020-01-01T00:00:00.200Z'));
+ childAfterSuccess.trace(result.success);
+ expect(emitted.length).toBe(before);
+ });
+
+ test('trace forwards MetricValue emissions unchanged', () => {
+ const emitted: MetricValue[] = [];
+ const consumer = (vals: MetricValue[]) => emitted.push(...vals);
+
+ const metric = Metric.fromName('X');
+ const value = metric.count.withValue(7);
+
+ const t = new MetricsTrace(consumer);
+ t.trace(value);
+
+ expect(emitted).toEqual([value]);
+ });
+});