Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
import { SuaveplanError } from "@suaveplan/error";
import { describe, expect, it } from "@suaveplan/testing/runner";
import {
IDEMPOTENCY_CODES,
IdempotencyConflictError,
IdempotencyError,
IdempotencyMismatchError,
LockAcquisitionError,
VersionConflictError,
} from "./idempotency-error.js";
describe("IDEMPOTENCY_CODES", () => {
it("contains all expected codes", { timeout: 5000 }, () => {
expect(IDEMPOTENCY_CODES.CONFLICT).toBe("IDEMPOTENCY.CONFLICT");
expect(IDEMPOTENCY_CODES.MISMATCH).toBe("IDEMPOTENCY.MISMATCH");
expect(IDEMPOTENCY_CODES.STORE_ERROR).toBe("IDEMPOTENCY.STORE_ERROR");
expect(IDEMPOTENCY_CODES.LOCK_ACQUISITION_FAILED).toBe(
"IDEMPOTENCY.LOCK_ACQUISITION_FAILED"
);
expect(IDEMPOTENCY_CODES.KEY_GENERATION_FAILED).toBe(
"IDEMPOTENCY.KEY_GENERATION_FAILED"
);
expect(IDEMPOTENCY_CODES.VERSION_CONFLICT).toBe(
"IDEMPOTENCY.VERSION_CONFLICT"
);
expect(IDEMPOTENCY_CODES.KEY_EXPIRED).toBe("IDEMPOTENCY.KEY_EXPIRED");
expect(IDEMPOTENCY_CODES.KEY_INVALID).toBe("IDEMPOTENCY.KEY_INVALID");
});
});
describe("IdempotencyConflictError", () => {
it("extends SuaveplanError and IdempotencyError", { timeout: 5000 }, () => {
const err = new IdempotencyConflictError("key-1");
expect(err).toBeInstanceOf(SuaveplanError);
expect(err).toBeInstanceOf(IdempotencyError);
expect(err).toBeInstanceOf(IdempotencyConflictError);
});
it("has the correct code", { timeout: 5000 }, () => {
const err = new IdempotencyConflictError("key-1");
expect(err.code).toBe("IDEMPOTENCY.CONFLICT");
});
it("exposes the key via accessor", { timeout: 5000 }, () => {
const err = new IdempotencyConflictError("my-key");
expect(err.key).toBe("my-key");
});
it("has a non-empty message", { timeout: 5000 }, () => {
const err = new IdempotencyConflictError("k");
expect(err.message.length).toBeGreaterThan(0);
});
it("captures context", { timeout: 5000 }, () => {
const err = new IdempotencyConflictError("ctx-key");
expect(err.context?.["key"]).toBe("ctx-key");
});
});
describe("IdempotencyMismatchError", () => {
it("extends SuaveplanError", { timeout: 5000 }, () => {
expect(new IdempotencyMismatchError("k")).toBeInstanceOf(
SuaveplanError
);
});
it("has the correct code", { timeout: 5000 }, () => {
expect(new IdempotencyMismatchError("k").code).toBe(
"IDEMPOTENCY.MISMATCH"
);
});
it("exposes key", { timeout: 5000 }, () => {
expect(new IdempotencyMismatchError("mkey").key).toBe("mkey");
});
});
describe("LockAcquisitionError", () => {
it("extends SuaveplanError", { timeout: 5000 }, () => {
expect(new LockAcquisitionError("k", 3)).toBeInstanceOf(SuaveplanError);
});
it("has the correct code", { timeout: 5000 }, () => {
expect(new LockAcquisitionError("k", 3).code).toBe(
"IDEMPOTENCY.LOCK_ACQUISITION_FAILED"
);
});
it("exposes key and attempts", { timeout: 5000 }, () => {
const err = new LockAcquisitionError("lk", 5);
expect(err.key).toBe("lk");
expect(err.attempts).toBe(5);
});
});
describe("VersionConflictError", () => {
it("extends SuaveplanError", { timeout: 5000 }, () => {
expect(new VersionConflictError("k", "fp1", "fp2")).toBeInstanceOf(
SuaveplanError
);
});
it("has the correct code", { timeout: 5000 }, () => {
expect(new VersionConflictError("k", "fp1", "fp2").code).toBe(
"IDEMPOTENCY.VERSION_CONFLICT"
);
});
it("exposes key", { timeout: 5000 }, () => {
expect(new VersionConflictError("vk", "a", "b").key).toBe("vk");
});
});