Files
2026-05-27 23:47:53 +01:00

150 lines
5.0 KiB
TypeScript

import { describe, expect, it } from "@suaveplan/testing/runner";
import fc from "fast-check";
import {
BITSET_HEADER_SIZE,
chunkIdsToRawBitset,
decodeBitset as decodeFramed,
encodeBitset as encodeFramed,
rawBitsetToChunkIds,
} from "../src/codec/bitset.js";
import { DMP_CODES, DmpError } from "../src/error-codes.js";
import {
decodeBitsetToChunkIds as decodeBitset,
encodeBitsetFromChunkIds as encodeBitset,
SELECT_FORM_BITSET_THRESHOLD,
selectForm,
selectWhole,
} from "../src/select/form.js";
describe("@suaveplan/drive-mesh-protocol — selectForm", () => {
it("rejects empty needed list with EMPTY_REQUEST", {
timeout: 5000,
}, () => {
expect(() => selectForm([])).toThrow(DmpError);
try {
selectForm([]);
} catch (err) {
expect(err).toBeInstanceOf(DmpError);
expect((err as DmpError).code).toBe(DMP_CODES.EMPTY_REQUEST);
}
});
it("returns kind:'specific' for ≤ threshold counts", {
timeout: 5000,
}, () => {
const result = selectForm([0, 5, 17]);
expect(result.kind).toBe("specific");
if (result.kind === "specific") {
expect(result.chunkIds).toEqual([0, 5, 17]);
}
});
it("returns kind:'specific' at exactly threshold", {
timeout: 5000,
}, () => {
const ids = Array.from(
{ length: SELECT_FORM_BITSET_THRESHOLD },
(_, i) => i
);
const result = selectForm(ids);
expect(result.kind).toBe("specific");
});
it("returns kind:'bitset' for > threshold counts", {
timeout: 5000,
}, () => {
const ids = Array.from(
{ length: SELECT_FORM_BITSET_THRESHOLD + 1 },
(_, i) => i
);
const result = selectForm(ids);
expect(result.kind).toBe("bitset");
if (result.kind === "bitset") {
expect(result.bytes).toBeInstanceOf(Uint8Array);
expect(result.bytes.length).toBeGreaterThan(BITSET_HEADER_SIZE);
}
});
it("honors a caller-supplied threshold override", { timeout: 5000 }, () => {
const result = selectForm([0, 1, 2], { threshold: 2 });
expect(result.kind).toBe("bitset");
});
it("threshold is exposed as the documented 64", { timeout: 5000 }, () => {
expect(SELECT_FORM_BITSET_THRESHOLD).toBe(64);
});
});
describe("@suaveplan/drive-mesh-protocol — selectWhole", () => {
it("returns the canonical whole form", { timeout: 5000 }, () => {
expect(selectWhole()).toEqual({ kind: "whole" });
});
});
describe("@suaveplan/drive-mesh-protocol — chunkIdsToRawBitset / rawBitsetToChunkIds", () => {
it("encodes a single bit", { timeout: 5000 }, () => {
const raw = chunkIdsToRawBitset([0], 1);
expect(raw.length).toBe(1);
expect(raw[0]).toBe(0b00000001);
});
it("encodes bits across byte boundaries", { timeout: 5000 }, () => {
const raw = chunkIdsToRawBitset([0, 7, 8, 15], 16);
expect(raw.length).toBe(2);
expect(raw[0]).toBe(0b10000001);
expect(raw[1]).toBe(0b10000001);
});
it("rejects negative chunk ids", { timeout: 5000 }, () => {
expect(() => chunkIdsToRawBitset([-1], 8)).toThrow(DmpError);
});
it("rejects ids past bitLength", { timeout: 5000 }, () => {
expect(() => chunkIdsToRawBitset([10], 8)).toThrow(DmpError);
});
it("decodes returns indexes in ascending order", { timeout: 5000 }, () => {
const raw = chunkIdsToRawBitset([10, 3, 17, 0], 18);
expect(rawBitsetToChunkIds(raw, 18)).toEqual([0, 3, 10, 17]);
});
});
describe("@suaveplan/drive-mesh-protocol — encodeBitset / decodeBitset (framed)", () => {
it("framed bytes carry the magic prefix", { timeout: 5000 }, () => {
const bytes = encodeBitset([0, 5, 17]);
expect(bytes[0]).toBe(0x44); // 'D'
expect(bytes[1]).toBe(0x4d); // 'M'
expect(bytes[2]).toBe(0x50); // 'P'
expect(bytes[3]).toBe(0x42); // 'B'
});
it("decode honours the embedded bit-length", { timeout: 5000 }, () => {
const framed = encodeFramed(chunkIdsToRawBitset([0, 5, 17], 18), 18);
const round = decodeFramed(framed);
expect(round.bitLength).toBe(18);
});
it("roundtrip property: decode(encode(x)) preserves the sorted set", {
timeout: 5000,
}, () => {
fc.assert(
fc.property(
fc
.array(fc.integer({ min: 0, max: 1023 }), {
minLength: 1,
maxLength: 64,
})
.map((arr) => Array.from(new Set(arr))),
(input) => {
const sorted = [...input].sort((a, b) => a - b);
const framed = encodeBitset(sorted);
const recovered = decodeBitset(framed);
expect(recovered).toEqual(sorted);
}
),
{ numRuns: 50 }
);
});
});