207 lines · 9.6 KB
import { beforeEach, describe, expect, mock, test } from "bun:test";
import { Database } from "bun:sqlite";
import { readdirSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { fakeStorage } from "./do-test-storage";

mock.module("cloudflare:workers", () => ({
  env: {},
  DurableObject: class {
    ctx: unknown;
    constructor(ctx: unknown) {
      this.ctx = ctx;
    }
  },
}));

type Statement = { sql: string; params: unknown[] };
let seeds: Record<string, Record<string, number>> = {};
let flushed: Statement[][] = [];
let failing: (statement: Statement) => boolean = () => false;

mock.module("./db", () => ({
  stmt: (sql: string, ...params: unknown[]): Statement => ({ sql, params }),
  first: async (sql: string, ...params: unknown[]) => {
    for (const [fragment, rows] of Object.entries(seeds)) {
      if (sql.includes(fragment)) return rows[String(params.at(-1))] !== undefined ? rows[String(params.at(-1))] : null;
    }
    return null;
  },
  batch: async (statements: Statement[]) => {
    if (statements.some(failing)) throw new Error("D1 rejected the batch");
    flushed.push(statements);
    return [];
  },
}));
mock.module("./sites/caps", () => ({ afterHostingFlush: async () => undefined }));

const { Counters } = await import("./counters-do");
const { REPO_PACK_BYTES, REPO_STARS, discussionUpvotesKey, usageKey } = await import("./counter-keys");
const { backoffMs, ISOLATE_AFTER } = await import("./do-flush");