Files
xingyue dbb7885ffd
CI / check (pull_request) Failing after 1m39s
chore: fix biome check errors (40 → 0)
- 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
2026-06-04 16:45:45 +08:00

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);
});
});