This commit is contained in:
2026-03-25 14:14:07 +01:00
parent d6b31e2ef7
commit a0073b4fb1
10368 changed files with 2214340 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
import { expect, describe, it } from "@jest/globals";
import { packAndUnpack } from "./util";
import data, { blob, objWithBlob } from "./data";
import { pack, unpack } from "../lib/binarypack";
describe("Blobs", () => {
it("replaces Blobs with ArrayBuffer ", async () => {
expect(await packAndUnpack(blob)).toStrictEqual(await blob.arrayBuffer());
});
it("replaces Blobs with ArrayBuffer in objects ", async () => {
const objWithAB = {
...objWithBlob,
blob: await objWithBlob.blob.arrayBuffer(),
};
expect(await packAndUnpack(objWithBlob)).toStrictEqual(objWithAB);
});
it("keep Text decodable", async () => {
for (const commit of data) {
const json = JSON.stringify(commit);
const blob = new Blob([json], { type: "application/json" });
const decoded = new TextDecoder().decode(
await packAndUnpack<ArrayBuffer>(blob),
);
expect(decoded).toStrictEqual(json);
}
});
});

View File

@@ -0,0 +1,16 @@
import { expect, describe, it } from "@jest/globals";
import { packAndUnpack } from "./util";
describe("Bugs", () => {
describe("Objects", () => {
it("replaces undefined with null ", async () => {
expect(packAndUnpack(undefined)).toBe(null);
});
});
describe("Numbers", () => {
it("gives back wrong value on INT64_MAX ", async () => {
expect(packAndUnpack(0x7fffffffffffffff)).not.toEqual(0x7fffffffffffffff);
});
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
import { expect, describe, it } from "@jest/globals";
import { packAndUnpack } from "./util";
describe("Binarypack", () => {
it("should keep valid UTF-8", async () => {
const values = [
0,
1,
-1,
//
Math.PI,
-Math.PI,
//8 bit
0x7f,
0x0f,
//16 bit
0x7fff,
0x0fff,
//32 bit
0x7fffffff,
0x0fffffff,
//64 bit
// 0x7FFFFFFFFFFFFFFF,
0x0fffffffffffffff,
];
// expect.assertions(values.length);
for (const v of values) {
expect(packAndUnpack(v)).toEqual(v);
}
});
});

View File

@@ -0,0 +1,113 @@
import { expect, describe, it } from "@jest/globals";
import commit_data from "./data";
import { packAndUnpack } from "./util";
describe("Binarypack", () => {
it("should keep objects intact", async () => {
const values = commit_data;
// expect.assertions(values.length);
for (const v of values) {
expect(packAndUnpack(v)).toEqual(v);
}
});
it("should keep very large object intact", async () => {
const v: { [key: number]: number } = {};
for (let i = 0; i < 0xffff; i++) {
v[i] = i;
}
expect(packAndUnpack(v)).toEqual(v);
});
it("should keep arrays of objects intact", async () => {
expect(packAndUnpack(commit_data)).toEqual(commit_data);
});
it("should keep empty and very large arrays intact", async () => {
const values = [[], Array(0xffff).fill(0)];
// expect.assertions(values.length);
for (const v of values) {
expect(packAndUnpack(v)).toEqual(v);
}
});
it("should keep null", async () => {
expect(packAndUnpack(null)).toEqual(null);
});
it("should transfer Uint8Array views correctly", async () => {
const arr = new Uint8Array(8);
for (let i = 0; i < 8; i++) arr[i] = i;
const v = new Uint8Array(arr.buffer, 4); // Half the array
const result = packAndUnpack<ArrayBuffer>(v);
expect(result).toBeInstanceOf(ArrayBuffer);
if (result instanceof ArrayBuffer)
expect(new Uint8Array(result)).toEqual(v);
});
it("should transfer Uint8Array as ArrayBuffer", async () => {
const values = [
new Uint8Array(),
new Uint8Array([0]),
new Uint8Array([0, 1, 2, 3, 4, 6, 7]),
new Uint8Array([0, 1, 2, 3, 4, 6, 78, 9, 10, 11, 12, 13, 14, 15]),
new Uint8Array([
0, 1, 2, 3, 4, 6, 78, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 30, 31,
]),
];
// expect.assertions(values.length);
for (const v of values) {
const result = packAndUnpack<ArrayBuffer>(v);
expect(result).toBeInstanceOf(ArrayBuffer);
if (result instanceof ArrayBuffer)
expect(new Uint8Array(result)).toEqual(v);
}
});
it("should transfer Int32Array as ArrayBuffer", async () => {
const values = [
new Int32Array([0].map((x) => -x)),
new Int32Array([0, 1, 2, 3, 4, 6, 7].map((x) => -x)),
new Int32Array(
[0, 1, 2, 3, 4, 6, 78, 9, 10, 11, 12, 13, 14, 15].map((x) => -x),
),
new Int32Array(
[
0, 1, 2, 3, 4, 6, 78, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 30, 31,
].map((x) => -x),
),
];
// expect.assertions(values.length);
for (const v of values) {
const result = packAndUnpack<ArrayBuffer>(v);
expect(result).toBeInstanceOf(ArrayBuffer);
if (result instanceof ArrayBuffer)
expect(new Int32Array(result)).toEqual(v);
}
});
it("should keep ArrayBuffers", async () => {
const values = [
new Uint8Array([]).buffer,
new Uint8Array([0]).buffer,
new Uint8Array([0, 1, 2, 3, 4, 6, 7]).buffer,
new Uint8Array([0, 1, 2, 3, 4, 6, 78, 9, 10, 11, 12, 13, 14, 15]).buffer,
new Uint8Array([
0, 1, 2, 3, 4, 6, 78, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 30, 31,
]).buffer,
];
// expect.assertions(values.length);
for (const v of values) {
expect(packAndUnpack<ArrayBuffer>(v)).toEqual(v);
}
});
it("should transfer Dates as String", async () => {
const values = [new Date(), new Date(Date.UTC(1, 1, 1, 1, 1, 1, 1))];
// expect.assertions(values.length);
for (const v of values) {
expect(packAndUnpack(v)).toEqual(v.toString());
}
});
});

View File

@@ -0,0 +1,52 @@
import { expect, describe, it } from "@jest/globals";
import { packAndUnpack } from "./util";
describe("Binarypack", () => {
it("should keep valid UTF-8", async () => {
const values = [
"",
"hello",
"café",
"中文",
"broccoli🥦līp𨋢grin😃ok",
"\u{10ffff}",
];
// expect.assertions(values.length);
for (const v of values) {
expect(packAndUnpack(v)).toEqual(v);
}
});
/**
* A Javascript string with unpaired surrogates is not actually valid
* UTF-16, and so it cannot be round-tripped to UTF-8 and back.
* The recommended way to handle this is to replace each unpaired surrogate
* with \uFFFD (the "replacement character").
*
* Note a surrogate pair means two adjacent Javascript characters where the
* first is in the range \uD800 - \uDBFF and the second is in the
* range \uDC00 - \uDFFF.
* To be valid UTF-16, Javascript characters from these ranges must *only*
* appear in surrogate pairs. An *unpaired* surrogate means any such
* Javascript character that is not paired up properly.
*
* https://github.com/peers/js-binarypack/issues/11#issuecomment-1445129237
*/
it("should replace unpaired surrogates", async () => {
const v = "un\ud800paired\udfffsurrogates";
const expected = v.replace(
/[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/g,
"\ufffd",
);
expect(await packAndUnpack(v)).toEqual(expected);
});
it("should encode very large strings", async () => {
const chunk = "ThisIsÁTèstString";
const v = chunk.repeat(1000);
expect(await packAndUnpack(v)).toEqual(v);
});
});

View File

@@ -0,0 +1,9 @@
import { pack, Packable, unpack, Unpackable } from "../lib/binarypack";
export const packAndUnpack = <T extends Unpackable>(data: Packable) => {
const encoded = pack(data);
if (encoded instanceof Promise) {
return encoded.then(unpack<T>);
}
return unpack<T>(encoded);
};