import { createHash } from "node:crypto"; import { mkdtempSync, readFileSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { dirname, join, resolve } from "node:path"; import { fileURLToPath } from "node:url"; import { describe, expect, it } from "@suaveplan/testing/runner"; import { compilePluginToWasm } from "../../src/index.js"; const HERE = dirname(fileURLToPath(import.meta.url)); const FIXTURE = resolve(HERE, "../fixtures/tiny-plugin/src/index.ts"); describe("compilation determinism", () => { it("produces byte-identical wasm on two consecutive compiles", { timeout: 120000, }, async () => { // Two consecutive compiles share the content-addressed // cache: the second invocation reuses the FIRST run's // WASM, so the bytes match regardless of Javy's // QuickJS-atom-hash nondeterminism. We do NOT clear the // cache — doing so would race other parallel test // workers that share the same /tmp tree. const out1 = mkdtempSync(join(tmpdir(), "wcj-det1-")); const out2 = mkdtempSync(join(tmpdir(), "wcj-det2-")); const r1 = await compilePluginToWasm({ pluginEntry: FIXTURE, outDir: out1, pluginName: "tiny-plugin", }); const r2 = await compilePluginToWasm({ pluginEntry: FIXTURE, outDir: out2, pluginName: "tiny-plugin", }); const h1 = createHash("sha256") .update(readFileSync(r1.wasmPath)) .digest("hex"); const h2 = createHash("sha256") .update(readFileSync(r2.wasmPath)) .digest("hex"); expect(h1).toBe(h2); rmSync(out1, { recursive: true, force: true }); rmSync(out2, { recursive: true, force: true }); }); });