import { mkdtempSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { describe, expect, it } from "@effect/vitest"; import { Effect, Exit } from "effect"; import { artifactStoreConformance } from "../seams/artifact-store.conformance"; import { scopeAddress, scopeAddressStorageKey } from "../seams/scope-address"; import { compareAndSwapSnapshotRef, makeGitArtifactStore } from "./git-artifact-store"; artifactStoreConformance("git", () => makeGitArtifactStore({ root: mkdtempSync(join(tmpdir(), "apps-artifacts-")) }), ); const run = (effect: Effect.Effect): Promise => Effect.runPromise(effect); describe("git ArtifactStore CAS", () => { it("returns a typed conflict when the expected head is stale", async () => { const root = mkdtempSync(join(tmpdir(), "apps-artifacts-cas-")); const address = scopeAddress("org", "s"); const scope = await run(makeGitArtifactStore({ root }).forScope(address)); const first = await run(scope.commit(new Map([["tools/a.ts", "a"]]), "first")); await run(scope.commit(new Map([["tools/a.ts", "b"]]), "second")); const repoDir = join(root, `${scopeAddressStorageKey(address)}.git`); const exit = await Effect.runPromiseExit( compareAndSwapSnapshotRef(repoDir, String(first.id), String(first.id)), ); expect(Exit.isFailure(exit)).toBe(true); expect(JSON.stringify(exit)).toContain("publish conflict"); expect(JSON.stringify(exit)).toContain('"conflict":true'); }); });