testShapesStaySmall

tcmts.core.test.shape.testShapesStaySmall · #tcckl42l · term

Shapes stay small, being kept with every version of their definition: a class itself (typeof Stream) is described by name, not by its statics, which can hold the class again (as Node's stream.Duplex.Duplex does), and a shape too big to be worth comparing is opaque.

import { analyzeFile } from "#codebase/tcmts/core/analyze";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";

export const testShapesStaySmall = () => {
  const dir = fs.mkdtempSync(path.join(os.tmpdir(), "tcm shape "));
  fs.writeFileSync(path.join(dir, "package.json"), JSON.stringify({ type: "module" }));
  const file = path.join(dir, "shapes.ts");
  const statics = ["A", "B", "C", "D", "E", "F", "G", "H"].map(
    (n) => `static ${n}: typeof Stream;`,
  );
  fs.writeFileSync(
    file,
    `export class Stream { ${statics.join(" ")} }
export const streams = (): Map<string, typeof Stream> => new Map();
export const big = ${JSON.stringify("x".repeat(70_000))};
`,
  );
  const { defs, errors, diagnostics } = analyzeFile(file, {
    cacheDir: path.join(dir, ".tcm", "cache"),
    resolveName: (name) => {
      throw new Error(`unknown ${name}`);
    },
  });
  assert.deepEqual([...errors, ...diagnostics.map((d) => d.message)], []);
  const shape = (name: string) => JSON.stringify(defs.find((d) => d.nameHint === name)!.shape);
  const stream = defs.find((d) => d.nameHint === "Stream")!.hash;
  assert.equal(
    shape("streams"),
    JSON.stringify([
      {
        k: "fn",
        params: [],
        ret: {
          k: "named",
          name: "Map",
          args: [
            { k: "prim", name: "string" },
            { k: "named", name: "typeof", args: [{ k: "ref", hash: stream, args: [] }] },
          ],
        },
      },
    ]),
  );
  assert.equal(shape("big"), JSON.stringify([{ k: "opaque" }]));
}

uses