Files
suaveplan/packages/foundation/data/pagination/src/otel/pagination-otel.test.ts
2026-05-27 23:47:53 +01:00

138 lines
5.1 KiB
TypeScript

import { afterEach, describe, expect, it } from "@suaveplan/testing/runner";
import {
getPaginationInstruments,
resetPaginationInstruments,
setPaginationMeterProvider,
} from "./pagination-otel.js";
afterEach(() => {
resetPaginationInstruments();
});
// ---------------------------------------------------------------------------
// Fake meter factory
// ---------------------------------------------------------------------------
function makeFakeMeterProvider() {
const calls: string[] = [];
const fakeMeter = {
createCounter: (name: string) => {
calls.push(`counter:${name}`);
return {
add: (_v: number, _attrs?: Record<string, string>) => undefined,
};
},
createHistogram: (name: string) => {
calls.push(`histogram:${name}`);
return {
record: (_v: number, _attrs?: Record<string, string>) =>
undefined,
};
},
};
return {
getMeter: (_name: string) => fakeMeter,
calls,
};
}
// ---------------------------------------------------------------------------
// getPaginationInstruments (no-op path — OTel not installed)
// ---------------------------------------------------------------------------
describe("getPaginationInstruments (no-op)", () => {
it("returns instruments with add and record methods", {
timeout: 5000,
}, () => {
const instruments = getPaginationInstruments();
expect(typeof instruments.requestTotal.add).toBe("function");
expect(typeof instruments.pageSize.record).toBe("function");
expect(typeof instruments.encodeDecode.record).toBe("function");
});
it("no-op instruments do not throw on add", { timeout: 5000 }, () => {
const { requestTotal } = getPaginationInstruments();
expect(() =>
requestTotal.add(1, { strategy: "cursor", outcome: "success" })
).not.toThrow();
});
it("no-op instruments do not throw on record", { timeout: 5000 }, () => {
const { pageSize, encodeDecode } = getPaginationInstruments();
expect(() => pageSize.record(10, { strategy: "offset" })).not.toThrow();
expect(() =>
encodeDecode.record(0.5, { direction: "encode", type: "cursor" })
).not.toThrow();
});
it("returns same instance on repeated calls", { timeout: 5000 }, () => {
const a = getPaginationInstruments();
const b = getPaginationInstruments();
expect(a).toBe(b);
});
it("resetPaginationInstruments forces re-initialisation", {
timeout: 5000,
}, () => {
const a = getPaginationInstruments();
resetPaginationInstruments();
const b = getPaginationInstruments();
expect(a).not.toBe(b);
});
});
// ---------------------------------------------------------------------------
// setPaginationMeterProvider — success path (injected provider)
// ---------------------------------------------------------------------------
describe("setPaginationMeterProvider (injected provider)", () => {
it("builds real instruments from the injected meter provider", {
timeout: 5000,
}, () => {
const provider = makeFakeMeterProvider();
setPaginationMeterProvider(provider);
const instr = getPaginationInstruments();
expect(typeof instr.requestTotal.add).toBe("function");
expect(typeof instr.pageSize.record).toBe("function");
expect(typeof instr.encodeDecode.record).toBe("function");
expect(provider.calls).toContain("counter:pagination.request.total");
expect(provider.calls).toContain("histogram:pagination.page.size");
expect(provider.calls).toContain(
"histogram:pagination.encode_decode.duration_ms"
);
});
it("instruments from the injected provider actually call through", {
timeout: 5000,
}, () => {
const addCalls: number[] = [];
const recordCalls: number[] = [];
const provider = {
getMeter: (_name: string) => ({
createCounter: (_n: string) => ({
add: (v: number) => addCalls.push(v),
}),
createHistogram: (_n: string) => ({
record: (v: number) => recordCalls.push(v),
}),
}),
};
setPaginationMeterProvider(
provider as Parameters<typeof setPaginationMeterProvider>[0]
);
const instr = getPaginationInstruments();
instr.requestTotal.add(1);
instr.pageSize.record(5);
expect(addCalls).toEqual([1]);
expect(recordCalls).toContain(5);
});
it("passing undefined clears any previously-installed provider", {
timeout: 5000,
}, () => {
const provider = makeFakeMeterProvider();
setPaginationMeterProvider(provider);
setPaginationMeterProvider(undefined);
// After clearing, the next get rebuilds via the global metrics API.
const instr = getPaginationInstruments();
expect(typeof instr.requestTotal.add).toBe("function");
});
});