dbb7885ffd
CI / check (pull_request) Failing after 1m39s
- Auto-fix: import sorting, formatting (17 files) - Unsafe auto-fix: unused vars, template literals (7 files) - Manual: nursery/noConsole → suspicious/noConsole suppression - Manual: suppress noExcessiveCognitiveComplexity for cmdThreadResume and parseWorkflowPayload - Manual: remove unused destructured vars in current-role tests Closes #48
131 lines
4.4 KiB
TypeScript
131 lines
4.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
CROCKFORD_BASE32_ALPHABET,
|
|
decodeCrockfordBase32Bits,
|
|
decodeCrockfordToUint64,
|
|
encodeCrockfordBase32Bits,
|
|
encodeUint64AsCrockford,
|
|
} from "../src/base32.js";
|
|
|
|
describe("CROCKFORD_BASE32_ALPHABET", () => {
|
|
it("has exactly 32 characters", () => {
|
|
expect(CROCKFORD_BASE32_ALPHABET).toHaveLength(32);
|
|
});
|
|
|
|
it("excludes I, L, O, U", () => {
|
|
expect(CROCKFORD_BASE32_ALPHABET).not.toContain("I");
|
|
expect(CROCKFORD_BASE32_ALPHABET).not.toContain("L");
|
|
expect(CROCKFORD_BASE32_ALPHABET).not.toContain("O");
|
|
expect(CROCKFORD_BASE32_ALPHABET).not.toContain("U");
|
|
});
|
|
});
|
|
|
|
describe("encodeCrockfordBase32Bits / decodeCrockfordBase32Bits", () => {
|
|
it("roundtrips zero with bitLength=5", () => {
|
|
const encoded = encodeCrockfordBase32Bits(0n, 5);
|
|
expect(encoded).toBe("0");
|
|
const decoded = decodeCrockfordBase32Bits(encoded, 5);
|
|
expect(decoded).toEqual({ ok: true, value: 0n });
|
|
});
|
|
|
|
it("roundtrips value 31 with bitLength=5", () => {
|
|
const encoded = encodeCrockfordBase32Bits(31n, 5);
|
|
expect(encoded).toBe("Z");
|
|
const decoded = decodeCrockfordBase32Bits(encoded, 5);
|
|
expect(decoded).toEqual({ ok: true, value: 31n });
|
|
});
|
|
|
|
it("roundtrips with bitLength=10", () => {
|
|
const encoded = encodeCrockfordBase32Bits(1023n, 10);
|
|
expect(encoded).toBe("ZZ");
|
|
const decoded = decodeCrockfordBase32Bits(encoded, 10);
|
|
expect(decoded).toEqual({ ok: true, value: 1023n });
|
|
});
|
|
|
|
it("roundtrips with non-multiple-of-5 bitLength", () => {
|
|
const value = 255n; // 8 bits
|
|
const encoded = encodeCrockfordBase32Bits(value, 8);
|
|
expect(encoded).toHaveLength(2); // 8 bits -> 10 bits padded -> 2 chars
|
|
const decoded = decodeCrockfordBase32Bits(encoded, 8);
|
|
expect(decoded).toEqual({ ok: true, value });
|
|
});
|
|
|
|
it("roundtrips large value", () => {
|
|
const value = (1n << 64n) - 1n;
|
|
const encoded = encodeCrockfordBase32Bits(value, 64);
|
|
const decoded = decodeCrockfordBase32Bits(encoded, 64);
|
|
expect(decoded).toEqual({ ok: true, value });
|
|
});
|
|
|
|
it("throws on bitLength <= 0", () => {
|
|
expect(() => encodeCrockfordBase32Bits(0n, 0)).toThrow("bitLength must be positive");
|
|
expect(() => encodeCrockfordBase32Bits(0n, -1)).toThrow("bitLength must be positive");
|
|
});
|
|
|
|
it("returns error on decode with bitLength <= 0", () => {
|
|
const result = decodeCrockfordBase32Bits("0", 0);
|
|
expect(result.ok).toBe(false);
|
|
});
|
|
|
|
it("returns error on invalid character", () => {
|
|
const result = decodeCrockfordBase32Bits("U", 5);
|
|
expect(result.ok).toBe(false);
|
|
});
|
|
|
|
it("returns error on wrong encoded length", () => {
|
|
const result = decodeCrockfordBase32Bits("00", 5);
|
|
expect(result.ok).toBe(false);
|
|
});
|
|
|
|
it("handles lowercase input on decode", () => {
|
|
const encoded = encodeCrockfordBase32Bits(10n, 5);
|
|
const decoded = decodeCrockfordBase32Bits(encoded.toLowerCase(), 5);
|
|
expect(decoded).toEqual({ ok: true, value: 10n });
|
|
});
|
|
});
|
|
|
|
describe("encodeUint64AsCrockford / decodeCrockfordToUint64", () => {
|
|
it("encodes to 13 characters", () => {
|
|
expect(encodeUint64AsCrockford(0n)).toHaveLength(13);
|
|
expect(encodeUint64AsCrockford(1n)).toHaveLength(13);
|
|
});
|
|
|
|
it("roundtrips 0n", () => {
|
|
const encoded = encodeUint64AsCrockford(0n);
|
|
expect(encoded).toBe("0000000000000");
|
|
const decoded = decodeCrockfordToUint64(encoded);
|
|
expect(decoded).toEqual({ ok: true, value: 0n });
|
|
});
|
|
|
|
it("roundtrips max uint64", () => {
|
|
const max = (1n << 64n) - 1n;
|
|
const encoded = encodeUint64AsCrockford(max);
|
|
const decoded = decodeCrockfordToUint64(encoded);
|
|
expect(decoded).toEqual({ ok: true, value: max });
|
|
});
|
|
|
|
it("roundtrips arbitrary value", () => {
|
|
const value = 0xdead_beef_cafe_baben;
|
|
const encoded = encodeUint64AsCrockford(value);
|
|
const decoded = decodeCrockfordToUint64(encoded);
|
|
expect(decoded).toEqual({ ok: true, value });
|
|
});
|
|
|
|
it("masks values beyond 64 bits", () => {
|
|
const over = (1n << 64n) + 42n;
|
|
const encoded = encodeUint64AsCrockford(over);
|
|
const decoded = decodeCrockfordToUint64(encoded);
|
|
expect(decoded).toEqual({ ok: true, value: 42n });
|
|
});
|
|
|
|
it("returns error for invalid input", () => {
|
|
const result = decodeCrockfordToUint64("!!!");
|
|
expect(result.ok).toBe(false);
|
|
});
|
|
|
|
it("returns error for wrong length", () => {
|
|
const result = decodeCrockfordToUint64("000");
|
|
expect(result.ok).toBe(false);
|
|
});
|
|
});
|