release: WRNexusJS 0.8.0
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { MetricsRegistry } from "../src/metrics.ts";
|
||||
import {
|
||||
createOperationTracer,
|
||||
createOtlpLogExporter,
|
||||
createPerformanceProfiler,
|
||||
createPrometheusPushExporter,
|
||||
createSentryCompatibleReporter,
|
||||
createZipkinExporter,
|
||||
renderPrometheus,
|
||||
} from "../src/integrations.ts";
|
||||
|
||||
describe("observability integrations", () => {
|
||||
test("records every framework operation kind and failures", async () => {
|
||||
const spans: any[] = [];
|
||||
const tracer = createOperationTracer({
|
||||
exporter: {
|
||||
export: (records) => {
|
||||
spans.push(...records);
|
||||
},
|
||||
},
|
||||
now: (() => {
|
||||
let time = 0;
|
||||
return () => (time += 5);
|
||||
})(),
|
||||
});
|
||||
for (const kind of [
|
||||
"database",
|
||||
"cache",
|
||||
"queue",
|
||||
"realtime",
|
||||
"server-action",
|
||||
"application",
|
||||
] as const)
|
||||
expect(await tracer.span(kind, `${kind}.work`, async () => kind)).toBe(kind);
|
||||
await expect(
|
||||
tracer.span("application", "failure", async () => {
|
||||
throw new Error("boom");
|
||||
}),
|
||||
).rejects.toThrow("boom");
|
||||
expect(spans.map((span) => span.attributes["wrnexus.span.kind"])).toContain("database");
|
||||
expect(spans.at(-1).status).toBe("error");
|
||||
});
|
||||
|
||||
test("exports Prometheus, Zipkin/Jaeger, OTLP logs and Sentry-compatible errors", async () => {
|
||||
const requests: Array<{ url: string; init?: RequestInit }> = [];
|
||||
const send = (async (url: URL | RequestInfo, init?: RequestInit) => {
|
||||
requests.push({ url: String(url), init });
|
||||
return new Response(null, { status: 200 });
|
||||
}) as typeof fetch;
|
||||
const registry = new MetricsRegistry(() => 10);
|
||||
registry.increment("http.requests", 1, { route: "/" });
|
||||
expect(renderPrometheus(registry.snapshot())).toContain('http_requests{route="/"} 1');
|
||||
await createPrometheusPushExporter("https://prom.test", { fetch: send }).export(
|
||||
registry.snapshot(),
|
||||
);
|
||||
const span = {
|
||||
name: "db",
|
||||
traceId: "1".repeat(32),
|
||||
spanId: "2".repeat(16),
|
||||
sampled: true,
|
||||
startTime: 1,
|
||||
endTime: 2,
|
||||
durationMs: 1,
|
||||
status: "ok" as const,
|
||||
attributes: {},
|
||||
};
|
||||
await createZipkinExporter("https://zipkin.test", { fetch: send }).export([span]);
|
||||
await createOtlpLogExporter("https://otlp.test", { fetch: send }).export([
|
||||
{
|
||||
timestamp: new Date(0).toISOString(),
|
||||
level: "info",
|
||||
message: "ready",
|
||||
service: "app",
|
||||
attributes: {},
|
||||
},
|
||||
]);
|
||||
expect(
|
||||
await createSentryCompatibleReporter("https://sentry.test", { fetch: send }).capture(
|
||||
new Error("bad"),
|
||||
),
|
||||
).toHaveLength(32);
|
||||
expect(requests).toHaveLength(4);
|
||||
});
|
||||
|
||||
test("profiles application operations", async () => {
|
||||
const profiles: any[] = [];
|
||||
let time = 0;
|
||||
const profile = createPerformanceProfiler({
|
||||
now: () => (time += 4),
|
||||
onProfile: (value) => profiles.push(value),
|
||||
});
|
||||
expect(await profile("render", () => "ok")).toBe("ok");
|
||||
expect(profiles[0]).toMatchObject({ name: "render", durationMs: 4 });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user