import { describe, expect, it, spyOn } from "bun:test";
import { timed } from "./timed";

describe("timed", () => {
  it("retourne le résultat de fn inchangé et logge label/ms/rows", async () => {
    const spy = spyOn(console, "log").mockImplementation(() => {});
    const rows = await timed(
      "stats.agg",
      { siteId: "s1", period: 28 },
      async () => [1, 2, 3],
    );
    expect(rows).toEqual([1, 2, 3]);
    const line = spy.mock.calls.find((c) => c[0] === "[query-timing]");
    expect(line).toBeDefined();
    const payload = JSON.parse(String(line?.[1]));
    expect(payload.label).toBe("stats.agg");
    expect(payload.rows).toBe(3);
    expect(payload.siteId).toBe("s1");
    expect(typeof payload.ms).toBe("number");
    spy.mockRestore();
  });

  it("résultat non-tableau → rows = -1", async () => {
    const spy = spyOn(console, "log").mockImplementation(() => {});
    const out = await timed("x", {}, async () => ({ ok: true }));
    expect(out).toEqual({ ok: true });
    const line = spy.mock.calls.find((c) => c[0] === "[query-timing]");
    expect(JSON.parse(String(line?.[1])).rows).toBe(-1);
    spy.mockRestore();
  });

  it("propage l'erreur de fn (et ne la masque pas)", async () => {
    const spy = spyOn(console, "log").mockImplementation(() => {});
    await expect(
      timed("boom", {}, async () => Promise.reject(new Error("x"))),
    ).rejects.toThrow("x");
    spy.mockRestore();
  });
});
