Files
2026-05-27 23:47:53 +01:00

64 lines
2.2 KiB
TypeScript

import { readdirSync, readFileSync, statSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "@suaveplan/testing/runner";
import type { TimersLike } from "@suaveplan/types";
import { AnalyticsTracker } from "../src/tracker/tracker.js";
import { BatchTransport } from "../src/transport/batch.js";
const noopTimers: TimersLike = {
setTimer: () => 0,
clearTimer: () => {},
};
function* walk(dir: string): Generator<string> {
for (const entry of readdirSync(dir)) {
const full = join(dir, entry);
const st = statSync(full);
if (st.isDirectory()) {
yield* walk(full);
} else if (full.endsWith(".ts") && !full.endsWith(".test.ts")) {
yield full;
}
}
}
describe("integration", () => {
it("tracker → batch transport → in-process endpoint round-trip", {
timeout: 5000,
}, async () => {
const observed: Array<{ events: unknown[] }> = [];
const fetchFn: typeof fetch = async (_url, init) => {
const body = init?.body as string;
observed.push(JSON.parse(body) as { events: unknown[] });
return new Response("", { status: 200 });
};
const transport = new BatchTransport({
endpoint: "/api/analytics",
fetchFn,
});
const tracker = new AnalyticsTracker(transport, {
batchSize: 1,
timers: noopTimers,
});
const seen: string[] = [];
tracker.events.on("track", () => seen.push("track"));
tracker.events.on("flush", ({ success }) =>
seen.push(`flush:${String(success)}`)
);
tracker.track("e");
await tracker.flush();
expect(observed.length).toBe(1);
expect((observed[0]?.events?.[0] as { name: string }).name).toBe("e");
expect(seen[0]).toBe("track");
expect(seen[seen.length - 1]).toBe("flush:true");
});
it("src/ contains no node: imports", { timeout: 5000 }, () => {
const srcDir = join(__dirname, "..", "src");
for (const file of walk(srcDir)) {
const text = readFileSync(file, "utf8");
expect(text).not.toMatch(/from\s+["']node:/);
}
});
});