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

63 lines
2.2 KiB
TypeScript

/**
* DMP-04 — `kind:'bitset'` payload via @suaveplan/bitpacker-compressed.
*
* Property-based round-trip across random bit densities, plus the
* "1000-chunk file with 3 needed chunks fits in <40 bytes" example
* from the spec.
*/
import { describe, expect, it } from "@suaveplan/testing/runner";
import fc from "fast-check";
import {
BITSET_HEADER_SIZE,
chunkIdsToRawBitset,
decodeFramedBitset,
encodeFramedBitset,
rawBitsetToChunkIds,
} from "../src/index.js";
describe("DMP-04 — bitset round-trip", () => {
it("bitset roundtrip preserves bit positions for random densities", {
timeout: 10000,
}, () => {
fc.assert(
fc.property(
fc
.array(fc.integer({ min: 0, max: 9999 }), {
minLength: 1,
maxLength: 200,
})
.map((arr) => Array.from(new Set(arr))),
(input) => {
const sorted = [...input].sort((a, b) => a - b);
const max = sorted[sorted.length - 1] as number;
const bitLength = max + 1;
const raw = chunkIdsToRawBitset(sorted, bitLength);
const framed = encodeFramedBitset(raw, bitLength);
const decoded = decodeFramedBitset(framed);
expect(decoded.bitLength).toBe(bitLength);
const recovered = rawBitsetToChunkIds(
decoded.raw,
decoded.bitLength
);
expect(recovered).toEqual(sorted);
}
),
{ numRuns: 50 }
);
});
it("1000-chunk file with 3 needed chunks fits in <165 bytes", {
timeout: 5000,
}, () => {
const needed = [100, 105, 200];
const bitLength = 1000;
const raw = chunkIdsToRawBitset(needed, bitLength);
const framed = encodeFramedBitset(raw, bitLength);
// header + 125 bytes raw bitset = ~137 bytes; well under 165.
expect(framed.length).toBeLessThan(BITSET_HEADER_SIZE + 200);
const back = rawBitsetToChunkIds(raw, bitLength);
expect(back).toEqual(needed);
});
});