160 lines · 4.5 KB · TypeScript
RawDownload
import { assert, describe, it } from "@effect/vitest";import { ProviderDriverKind } from "@t3tools/contracts";import * as Duration from "effect/Duration";import * as Effect from "effect/Effect";import * as Fiber from "effect/Fiber";import * as Metric from "effect/Metric";import * as TestClock from "effect/testing/TestClock"; import { withMetrics } from "./Metrics.ts"; const hasMetricSnapshot = (  snapshots: ReadonlyArray<Metric.Metric.Snapshot>,  id: string,  attributes: Readonly<Record<string, string>>,) =>  snapshots.some(    (snapshot) =>      snapshot.id === id &&      Object.entries(attributes).every(([key, value]) => snapshot.attributes?.[key] === value),  ); const findHistogramSnapshot = (  snapshots: ReadonlyArray<Metric.Metric.Snapshot>,  id: string,  attributes: Readonly<Record<string, string>>,) =>  snapshots.find(    (snapshot): snapshot is Extract<Metric.Metric.Snapshot, { readonly type: "Histogram" }> =>      snapshot.type === "Histogram" &&      snapshot.id === id &&      Object.entries(attributes).every(([key, value]) => snapshot.attributes?.[key] === value),  ); describe("withMetrics", () => {  it.effect("supports pipe-style usage", () =>    Effect.gen(function* () {      const counter = Metric.counter("with_metrics_pipe_total");      const timer = Metric.timer("with_metrics_pipe_duration");       const result = yield* Effect.succeed("ok").pipe(        withMetrics({          counter,          timer,          attributes: {            operation: "pipe",          },        }),      );       assert.equal(result, "ok");       const snapshots = yield* Metric.snapshot;      assert.equal(        hasMetricSnapshot(snapshots, "with_metrics_pipe_total", {          operation: "pipe",          outcome: "success",        }),        true,      );      assert.equal(        hasMetricSnapshot(snapshots, "with_metrics_pipe_duration", {          operation: "pipe",        }),        true,      );    }),  );   it.effect("supports direct invocation", () =>    Effect.gen(function* () {      const counter = Metric.counter("with_metrics_direct_total");       yield* withMetrics(Effect.fail("boom"), {        counter,        attributes: {          operation: "direct",        },      }).pipe(Effect.exit);       const snapshots = yield* Metric.snapshot;      assert.equal(        hasMetricSnapshot(snapshots, "with_metrics_direct_total", {          operation: "direct",          outcome: "failure",        }),        true,      );    }),  );   it.effect("evaluates attributes lazily after the wrapped effect runs", () =>    Effect.gen(function* () {      const counter = Metric.counter("with_metrics_lazy_total");      const timer = Metric.timer("with_metrics_lazy_duration");      let provider = ProviderDriverKind.make("unknown");      const lazyInittedProvider = ProviderDriverKind.make("codex");       yield* Effect.sync(() => {        provider = lazyInittedProvider;      }).pipe(        withMetrics({          counter,          timer,          attributes: () => ({            provider,            operation: "lazy",          }),        }),      );       const snapshots = yield* Metric.snapshot;      assert.equal(        hasMetricSnapshot(snapshots, "with_metrics_lazy_total", {          provider: lazyInittedProvider,          operation: "lazy",          outcome: "success",        }),        true,      );      assert.equal(        hasMetricSnapshot(snapshots, "with_metrics_lazy_duration", {          provider: lazyInittedProvider,          operation: "lazy",        }),        true,      );    }),  );   it.effect("records timer durations from nanosecond clock readings", () =>    Effect.gen(function* () {      const duration = Duration.nanos(1_500_000n);      const timer = Metric.timer("with_metrics_nanos_duration");       yield* Effect.gen(function* () {        const fiber = yield* Effect.sleep(duration).pipe(          withMetrics({            timer,            attributes: {              operation: "nanos",            },          }),          Effect.forkChild,        );         yield* Effect.yieldNow;        yield* TestClock.adjust(duration);        yield* Fiber.join(fiber);      }).pipe(Effect.provide(TestClock.layer()));       const snapshots = yield* Metric.snapshot;      const snapshot = findHistogramSnapshot(snapshots, "with_metrics_nanos_duration", {        operation: "nanos",      });       assert.equal(snapshot?.state.count, 1);      assert.equal(snapshot?.state.sum, 1.5);    }),  );});