// ♓🌟 Piscēs ∷ binary.test.js
// ====================================================================
//
-// Copyright © 2020–2022 Lady [@ Lady’s Computer].
+// Copyright © 2020–2023 Lady [@ Lady’s Computer].
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
it,
} from "./dev-deps.js";
import {
+ arrayBufferSlice,
+ base16Binary,
+ base16String,
+ base32Binary,
+ base32String,
base64Binary,
base64String,
filenameSafeBase64Binary,
filenameSafeBase64String,
+ get16BitSignedIntegralItem,
+ get16BitUnsignedIntegralItem,
+ get32BitFloatingPointItem,
+ get32BitSignedIntegralItem,
+ get32BitUnsignedIntegralItem,
+ get64BitFloatingPointItem,
+ get64BitSignedIntegralItem,
+ get64BitUnsignedIntegralItem,
+ get8BitSignedIntegralItem,
+ get8BitUnsignedIntegralItem,
+ isArrayBuffer,
+ isArrayBufferView,
+ isBase16,
+ isBase32,
isBase64,
isFilenameSafeBase64,
+ isSharedArrayBuffer,
+ isTypedArray,
+ isWRMGBase32,
+ set16BitIntegralItem,
+ set32BitFloatingPointItem,
+ set32BitIntegralItem,
+ set64BitFloatingPointItem,
+ set64BitIntegralItem,
+ set8BitIntegralItem,
+ toArrayBuffer,
+ wrmgBase32Binary,
+ wrmgBase32String,
} from "./binary.js";
-const base64s = {
- "AGIAYQBzAGUANgA0": "base64",
- "R/Q=": new Uint16Array([62535]),
- "S0lCSQ==": new Uint8ClampedArray([75, 73, 66, 73]).buffer,
- YmFzZTY0: new DataView(
- new Uint8Array([98, 97, 115, 101, 54, 52]).buffer,
- ),
-};
+// These tests assume a LITTLE‐ENDIAN environment.
+const data = new Map([
+ ["", {
+ base16: "",
+ base32: "",
+ base64: "",
+ wrmg: "",
+ }],
+ ["base64", {
+ base16: "006200610073006500360034",
+ base32: "ABRAAYIAOMAGKABWAA2A====",
+ base64: "AGIAYQBzAGUANgA0",
+ wrmg: "01H00R80EC06A01P00T0",
+ }],
+ [new Uint16Array([62535]), {
+ base16: "47F4",
+ base32: "I72A====",
+ base64: "R/Q=",
+ wrmg: "8ZT0",
+ }],
+ [new Uint8ClampedArray([75, 73, 66, 73]).buffer, {
+ base16: "4B494249",
+ base32: "JNEUESI=",
+ base64: "S0lCSQ==",
+ wrmg: "9D4M4J8",
+ }],
+ [new DataView(new Uint8Array([98, 97, 115, 101, 54, 52]).buffer), {
+ base16: "626173653634",
+ base32: "MJQXGZJWGQ======",
+ base64: "YmFzZTY0",
+ wrmg: "C9GQ6S9P6G",
+ }],
+
+ // The following three examples are from RFC 3548.
+ [new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9, 0x7E]), {
+ base16: "14FB9C03D97E",
+ base32: "CT5ZYA6ZPY======",
+ base64: "FPucA9l+",
+ wrmg: "2KXSR0YSFR",
+ }],
+ [new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9]), {
+ base16: "14FB9C03D9",
+ base32: "CT5ZYA6Z",
+ base64: "FPucA9k=",
+ wrmg: "2KXSR0YS",
+ }],
+ [new Uint8Array([0x14, 0xFB, 0x9C, 0x03]), {
+ base16: "14FB9C03",
+ base32: "CT5ZYAY=",
+ base64: "FPucAw==",
+ wrmg: "2KXSR0R",
+ }],
+
+ // The following examples are from the Ruby base32 gem.
+ [new Uint8Array([0x28]), {
+ base16: "28",
+ base32: "FA======",
+ base64: "KA==",
+ wrmg: "50",
+ }],
+ [new Uint8Array([0xD6]), {
+ base16: "D6",
+ base32: "2Y======",
+ base64: "1g==",
+ wrmg: "TR",
+ }],
+ [new Uint16Array([0xF8D6]), {
+ base16: "D6F8",
+ base32: "234A====",
+ base64: "1vg=",
+ wrmg: "TVW0",
+ }],
+ [new Uint8Array([0xD6, 0xF8, 0x00]), {
+ base16: "D6F800",
+ base32: "234AA===",
+ base64: "1vgA",
+ wrmg: "TVW00",
+ }],
+ [new Uint8Array([0xD6, 0xF8, 0x10]), {
+ base16: "D6F810",
+ base32: "234BA===",
+ base64: "1vgQ",
+ wrmg: "TVW10",
+ }],
+ [new Uint32Array([0x0C11F8D6]), {
+ base16: "D6F8110C",
+ base32: "234BCDA=",
+ base64: "1vgRDA==",
+ wrmg: "TVW1230",
+ }],
+ [new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]), {
+ base16: "D6F8110C80",
+ base32: "234BCDEA",
+ base64: "1vgRDIA=",
+ wrmg: "TVW12340",
+ }],
+ [new Uint16Array([0xF8D6, 0x0C11, 0x3085]), {
+ base16: "D6F8110C8530",
+ base32: "234BCDEFGA======",
+ base64: "1vgRDIUw",
+ wrmg: "TVW1234560",
+ }],
+]);
+
+describe("arrayBufferSlice", () => {
+ it("[[Call]] slices an `ArrayBuffer`", () => {
+ const baseBuffer = Uint8Array.from([2, 3, 1, 9, 8, 5]).buffer;
+ assertEquals(
+ new Uint8Array(arrayBufferSlice(baseBuffer, 1, 4)),
+ Uint8Array.from([3, 1, 9]),
+ );
+ });
+
+ it("[[Call]] slices an `SharedArrayBuffer`", () => {
+ const baseBuffer = new SharedArrayBuffer(6);
+ new Uint8Array(baseBuffer).set([2, 3, 1, 9, 8, 5], 0);
+ assertEquals(
+ new Uint8Array(arrayBufferSlice(baseBuffer, 1, 4)),
+ Uint8Array.from([3, 1, 9]),
+ );
+ });
+
+ it("[[Call]] throws for others", () => {
+ [
+ undefined,
+ null,
+ true,
+ Symbol(),
+ 27,
+ 98n,
+ {},
+ [],
+ () => {},
+ new Proxy({}, {}),
+ "string",
+ new DataView(new ArrayBuffer()),
+ new Uint8Array(),
+ ].forEach((value) =>
+ assertThrows(() => arrayBufferSlice(value, 0, 0))
+ );
+ });
+});
+
+describe("base16Binary", () => {
+ it("[[Call]] returns the correct data", () => {
+ assertEquals(
+ new Uint8Array(base16Binary("")),
+ new Uint8Array([]),
+ "<empty>",
+ );
+ assertEquals(
+ new Uint8Array(base16Binary("006200610073006500360034")),
+ Uint8Array.from(
+ "\u{0}b\u{0}a\u{0}s\u{0}e\u{0}6\u{0}4",
+ ($) => $.charCodeAt(0),
+ ),
+ "006200610073006500360034",
+ );
+ assertEquals(
+ new Uint16Array(base16Binary("47F4")),
+ new Uint16Array([62535]),
+ "47F4",
+ );
+ assertEquals(
+ new Uint8ClampedArray(base16Binary("4B494249")),
+ new Uint8ClampedArray([75, 73, 66, 73]),
+ "4B494249",
+ );
+ assertEquals(
+ new Uint8Array(base16Binary("626173653634")),
+ new Uint8Array([98, 97, 115, 101, 54, 52]),
+ "626173653634",
+ );
+ assertEquals(
+ new Uint8Array(base16Binary("14FB9C03D97E")),
+ new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9, 0x7E]),
+ "14FB9C03D97E",
+ );
+ assertEquals(
+ new Uint8Array(base16Binary("14FB9C03D9")),
+ new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9]),
+ "14FB9C03D9",
+ );
+ assertEquals(
+ new Uint8Array(base16Binary("14FB9C03")),
+ new Uint8Array([0x14, 0xFB, 0x9C, 0x03]),
+ "14FB9C03",
+ );
+ assertEquals(
+ new Uint8Array(base16Binary("28")),
+ new Uint8Array([0x28]),
+ "28",
+ );
+ assertEquals(
+ new Uint8Array(base16Binary("D6")),
+ new Uint8Array([0xD6]),
+ "D6",
+ );
+ assertEquals(
+ new Uint16Array(base16Binary("D6F8")),
+ new Uint16Array([0xF8D6]),
+ "D6F8",
+ );
+ assertEquals(
+ new Uint8Array(base16Binary("D6F800")),
+ new Uint8Array([0xD6, 0xF8, 0x00]),
+ "D6F800",
+ );
+ assertEquals(
+ new Uint8Array(base16Binary("D6F810")),
+ new Uint8Array([0xD6, 0xF8, 0x10]),
+ "D6F810",
+ );
+ assertEquals(
+ new Uint32Array(base16Binary("D6F8110C")),
+ new Uint32Array([0x0C11F8D6]),
+ "D6F8110C",
+ );
+ assertEquals(
+ new Uint8Array(base16Binary("D6F8110C80")),
+ new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]),
+ "D6F8110C80",
+ );
+ assertEquals(
+ new Uint16Array(base16Binary("D6F8110C8530")),
+ new Uint16Array([0xF8D6, 0x0C11, 0x3085]),
+ "D6F8110C8530",
+ );
+ });
+
+ it("[[Call]] is case‐insensitive", () => {
+ assertEquals(
+ new Uint8Array(base16Binary("d6f8110C80")),
+ new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]),
+ "d6f8110C80",
+ );
+ });
+
+ it("[[Call]] throws when provided with an invalid character", () => {
+ assertThrows(() => base16Binary("ABCG"));
+ });
+
+ it("[[Call]] throws when provided with a length with a remainder of 1 when divided by 2", () => {
+ assertThrows(() => base16Binary("A"));
+ assertThrows(() => base16Binary("ABC"));
+ });
+});
+
+describe("base16String", () => {
+ it("[[Call]] returns the correct string", () => {
+ for (const [source, { base16 }] of data) {
+ assertStrictEquals(base16String(source), base16);
+ }
+ });
+});
+
+describe("base32Binary", () => {
+ it("[[Call]] returns the correct data", () => {
+ assertEquals(
+ new Uint8Array(base32Binary("")),
+ new Uint8Array([]),
+ "<empty>",
+ );
+ assertEquals(
+ new Uint8Array(base32Binary("ABRAAYIAOMAGKABWAA2A====")),
+ Uint8Array.from(
+ "\u{0}b\u{0}a\u{0}s\u{0}e\u{0}6\u{0}4",
+ ($) => $.charCodeAt(0),
+ ),
+ "ABRAAYIAOMAGKABWAA2A====",
+ );
+ assertEquals(
+ new Uint16Array(base32Binary("I72A====")),
+ new Uint16Array([62535]),
+ "I72A====",
+ );
+ assertEquals(
+ new Uint8ClampedArray(base32Binary("JNEUESI=")),
+ new Uint8ClampedArray([75, 73, 66, 73]),
+ "JNEUESI=",
+ );
+ assertEquals(
+ new Uint8Array(base32Binary("MJQXGZJWGQ======")),
+ new Uint8Array([98, 97, 115, 101, 54, 52]),
+ "MJQXGZJWGQ======",
+ );
+ assertEquals(
+ new Uint8Array(base32Binary("CT5ZYA6ZPY======")),
+ new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9, 0x7E]),
+ "CT5ZYA6ZPY======",
+ );
+ assertEquals(
+ new Uint8Array(base32Binary("CT5ZYA6Z")),
+ new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9]),
+ "CT5ZYA6Z",
+ );
+ assertEquals(
+ new Uint8Array(base32Binary("CT5ZYAY=")),
+ new Uint8Array([0x14, 0xFB, 0x9C, 0x03]),
+ "CT5ZYAY=",
+ );
+ assertEquals(
+ new Uint8Array(base32Binary("FA======")),
+ new Uint8Array([0x28]),
+ "FA======",
+ );
+ assertEquals(
+ new Uint8Array(base32Binary("2Y======")),
+ new Uint8Array([0xD6]),
+ "2Y======",
+ );
+ assertEquals(
+ new Uint16Array(base32Binary("234A====")),
+ new Uint16Array([0xF8D6]),
+ "234A====",
+ );
+ assertEquals(
+ new Uint8Array(base32Binary("234AA===")),
+ new Uint8Array([0xD6, 0xF8, 0x00]),
+ "234AA===",
+ );
+ assertEquals(
+ new Uint8Array(base32Binary("234BA===")),
+ new Uint8Array([0xD6, 0xF8, 0x10]),
+ "234BA===",
+ );
+ assertEquals(
+ new Uint32Array(base32Binary("234BCDA=")),
+ new Uint32Array([0x0C11F8D6]),
+ "234BCDA=",
+ );
+ assertEquals(
+ new Uint8Array(base32Binary("234BCDEA")),
+ new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]),
+ "234BCDEA",
+ );
+ assertEquals(
+ new Uint16Array(base32Binary("234BCDEFGA======")),
+ new Uint16Array([0xF8D6, 0x0C11, 0x3085]),
+ "234BCDEFGA======",
+ );
+ });
+
+ it("[[Call]] is case‐insensitive", () => {
+ assertEquals(
+ new Uint8Array(base32Binary("234bcdEA")),
+ new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]),
+ "234bcdEA",
+ );
+ });
+
+ it("[[Call]] throws when provided with an invalid character", () => {
+ assertThrows(() => base32Binary("ABC0"));
+ assertThrows(() => base32Binary("ABC1"));
+ assertThrows(() => base32Binary("ABC8"));
+ assertThrows(() => base32Binary("ABC9"));
+ });
+
+ it("[[Call]] throws when provided with an invalid equals", () => {
+ assertThrows(() => base32Binary("CT3ZYAY=="));
+ });
+
+ it("[[Call]] throws when provided with a length with a remainder of 1, 3 ∣ 6 when divided by 8", () => {
+ assertThrows(() => base32Binary("234BCDEAA"));
+ assertThrows(() => base32Binary("234BCDEAA======="));
+ assertThrows(() => base32Binary("UHI"));
+ assertThrows(() => base32Binary("UHIUJD"));
+ });
+});
+
+describe("base32String", () => {
+ it("[[Call]] returns the correct string", () => {
+ for (const [source, { base32 }] of data) {
+ assertStrictEquals(base32String(source), base32);
+ }
+ });
+});
describe("base64Binary", () => {
it("[[Call]] returns the correct data", () => {
assertEquals(
- base64Binary("AGIAYQBzAGUANgA0"),
- new Uint8Array(
- Array.prototype.map.call(
- "\u{0}b\u{0}a\u{0}s\u{0}e\u{0}6\u{0}4",
- ($) => $.charCodeAt(0),
- ),
- ).buffer,
+ new Uint8Array(base64Binary("")),
+ new Uint8Array([]),
+ "<empty>",
+ );
+ assertEquals(
+ new Uint8Array(base64Binary("AGIAYQBzAGUANgA0")),
+ Uint8Array.from(
+ "\u{0}b\u{0}a\u{0}s\u{0}e\u{0}6\u{0}4",
+ ($) => $.charCodeAt(0),
+ ),
"AGIAYQBzAGUANgA0",
);
assertEquals(
- base64Binary("R/Q="),
- new Uint16Array([62535]).buffer,
+ new Uint16Array(base64Binary("R/Q=")),
+ new Uint16Array([62535]),
"R/Q=",
);
assertEquals(
- base64Binary("S0lCSQ=="),
- new Uint8ClampedArray([75, 73, 66, 73]).buffer,
+ new Uint8ClampedArray(base64Binary("S0lCSQ==")),
+ new Uint8ClampedArray([75, 73, 66, 73]),
"S0lCSQ==",
);
assertEquals(
- base64Binary("YmFzZTY0"),
- new Uint8Array([98, 97, 115, 101, 54, 52]).buffer,
+ new Uint8Array(base64Binary("YmFzZTY0")),
+ new Uint8Array([98, 97, 115, 101, 54, 52]),
"YmFzZTY0",
);
+ assertEquals(
+ new Uint8Array(base64Binary("FPucA9l+")),
+ new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9, 0x7E]),
+ "FPucA9l+",
+ );
+ assertEquals(
+ new Uint8Array(base64Binary("FPucA9k=")),
+ new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9]),
+ "FPucA9k=",
+ );
+ assertEquals(
+ new Uint8Array(base64Binary("FPucAw==")),
+ new Uint8Array([0x14, 0xFB, 0x9C, 0x03]),
+ "FPucAw==",
+ );
+ assertEquals(
+ new Uint8Array(base64Binary("KA==")),
+ new Uint8Array([0x28]),
+ "KA==",
+ );
+ assertEquals(
+ new Uint8Array(base64Binary("1g==")),
+ new Uint8Array([0xD6]),
+ "1g==",
+ );
+ assertEquals(
+ new Uint16Array(base64Binary("1vg")),
+ new Uint16Array([0xF8D6]),
+ "1vg",
+ );
+ assertEquals(
+ new Uint8Array(base64Binary("1vgA")),
+ new Uint8Array([0xD6, 0xF8, 0x00]),
+ "1vgA",
+ );
+ assertEquals(
+ new Uint8Array(base64Binary("1vgQ")),
+ new Uint8Array([0xD6, 0xF8, 0x10]),
+ "1vgQ",
+ );
+ assertEquals(
+ new Uint32Array(base64Binary("1vgRDA==")),
+ new Uint32Array([0x0C11F8D6]),
+ "1vgRDA==",
+ );
+ assertEquals(
+ new Uint8Array(base64Binary("1vgRDIA=")),
+ new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]),
+ "1vgRDIA=",
+ );
+ assertEquals(
+ new Uint16Array(base64Binary("1vgRDIUw")),
+ new Uint16Array([0xF8D6, 0x0C11, 0x3085]),
+ "1vgRDIUw",
+ );
});
it("[[Call]] throws when provided with an invalid character", () => {
describe("base64String", () => {
it("[[Call]] returns the correct string", () => {
- Object.entries(base64s).forEach(([key, value]) =>
- assertStrictEquals(base64String(value), key)
- );
+ for (const [source, { base64 }] of data) {
+ assertStrictEquals(base64String(source), base64);
+ }
});
});
describe("filenameSafeBase64Binary", () => {
it("[[Call]] returns the correct data", () => {
assertEquals(
- filenameSafeBase64Binary("AGIAYQBzAGUANgA0"),
- new Uint8Array(
- Array.prototype.map.call(
- "\u{0}b\u{0}a\u{0}s\u{0}e\u{0}6\u{0}4",
- ($) => $.charCodeAt(0),
- ),
- ).buffer,
+ new Uint8Array(filenameSafeBase64Binary("")),
+ new Uint8Array([]),
+ "<empty>",
+ );
+ assertEquals(
+ new Uint8Array(filenameSafeBase64Binary("AGIAYQBzAGUANgA0")),
+ Uint8Array.from(
+ "\u{0}b\u{0}a\u{0}s\u{0}e\u{0}6\u{0}4",
+ ($) => $.charCodeAt(0),
+ ),
"AGIAYQBzAGUANgA0",
);
assertEquals(
- filenameSafeBase64Binary("R_Q="),
- new Uint16Array([62535]).buffer,
+ new Uint16Array(filenameSafeBase64Binary("R_Q=")),
+ new Uint16Array([62535]),
"R/Q=",
);
assertEquals(
- filenameSafeBase64Binary("S0lCSQ=="),
- new Uint8ClampedArray([75, 73, 66, 73]).buffer,
+ new Uint8ClampedArray(filenameSafeBase64Binary("S0lCSQ==")),
+ new Uint8ClampedArray([75, 73, 66, 73]),
"S0lCSQ==",
);
assertEquals(
- filenameSafeBase64Binary("YmFzZTY0"),
- new Uint8Array([98, 97, 115, 101, 54, 52]).buffer,
+ new Uint8Array(filenameSafeBase64Binary("YmFzZTY0")),
+ new Uint8Array([98, 97, 115, 101, 54, 52]),
"YmFzZTY0",
);
+ assertEquals(
+ new Uint8Array(filenameSafeBase64Binary("KA==")),
+ new Uint8Array([0x28]),
+ "KA==",
+ );
+ assertEquals(
+ new Uint8Array(filenameSafeBase64Binary("1g==")),
+ new Uint8Array([0xD6]),
+ "1g==",
+ );
+ assertEquals(
+ new Uint16Array(filenameSafeBase64Binary("1vg")),
+ new Uint16Array([0xF8D6]),
+ "1vg",
+ );
+ assertEquals(
+ new Uint8Array(filenameSafeBase64Binary("1vgA")),
+ new Uint8Array([0xD6, 0xF8, 0x00]),
+ "1vgA",
+ );
+ assertEquals(
+ new Uint8Array(filenameSafeBase64Binary("1vgQ")),
+ new Uint8Array([0xD6, 0xF8, 0x10]),
+ "1vgQ",
+ );
+ assertEquals(
+ new Uint32Array(filenameSafeBase64Binary("1vgQDA==")),
+ new Uint32Array([0x0C10F8D6]),
+ "1vgQDA==",
+ );
+ assertEquals(
+ new Uint8Array(filenameSafeBase64Binary("1vgQDIA=")),
+ new Uint8Array([0xD6, 0xF8, 0x10, 0x0C, 0x80]),
+ "1vgQDIA=",
+ );
+ assertEquals(
+ new Uint16Array(filenameSafeBase64Binary("1vgQDIUw")),
+ new Uint16Array([0xF8D6, 0x0C10, 0x3085]),
+ "1vgQDIUw",
+ );
});
it("[[Call]] throws when provided with an invalid character", () => {
describe("filenameSafeBase64String", () => {
it("[[Call]] returns the correct string", () => {
- Object.entries(base64s).forEach(([key, value]) =>
+ for (const [source, { base64 }] of data) {
assertStrictEquals(
- filenameSafeBase64String(value),
- key.replace("+", "-").replace("/", "_"),
- )
+ filenameSafeBase64String(source),
+ base64.replace("+", "-").replace("/", "_"),
+ );
+ }
+ });
+});
+
+describe("get8BitSignedIntegralItem", () => {
+ it("[[Call]] gets the item", () => {
+ const buffer = Int8Array.from([0, -1, 0]).buffer;
+ assertStrictEquals(get8BitSignedIntegralItem(buffer, 1), -1n);
+ assertStrictEquals(
+ get8BitSignedIntegralItem(new DataView(buffer), 1),
+ -1n,
+ );
+ assertStrictEquals(
+ get8BitSignedIntegralItem(new Uint8Array(buffer), 1),
+ -1n,
+ );
+ });
+});
+
+describe("get8BitUnsignedIntegralItem", () => {
+ it("[[Call]] gets the item", () => {
+ const buffer = Int8Array.from([0, -1, 0]).buffer;
+ assertStrictEquals(get8BitUnsignedIntegralItem(buffer, 1), 255n);
+ assertStrictEquals(
+ get8BitUnsignedIntegralItem(new DataView(buffer), 1),
+ 255n,
+ );
+ assertStrictEquals(
+ get8BitUnsignedIntegralItem(new Int8Array(buffer), 1),
+ 255n,
+ );
+ });
+});
+
+describe("get16BitSignedIntegralItem", () => {
+ it("[[Call]] gets the item", () => {
+ const buffer = Int8Array.from([0, 0, -1, -1, 0, 0]).buffer;
+ assertStrictEquals(get16BitSignedIntegralItem(buffer, 2), -1n);
+ assertStrictEquals(
+ get16BitSignedIntegralItem(new DataView(buffer), 2),
+ -1n,
+ );
+ assertStrictEquals(
+ get16BitSignedIntegralItem(new Uint16Array(buffer), 2),
+ -1n,
+ );
+ });
+});
+
+describe("get16BitUnsignedIntegralItem", () => {
+ it("[[Call]] gets the item", () => {
+ const buffer = Int8Array.from([0, 0, -1, -1, 0, 0]).buffer;
+ assertStrictEquals(
+ get16BitUnsignedIntegralItem(buffer, 2),
+ (1n << 16n) - 1n,
+ );
+ assertStrictEquals(
+ get16BitUnsignedIntegralItem(new DataView(buffer), 2),
+ (1n << 16n) - 1n,
+ );
+ assertStrictEquals(
+ get16BitUnsignedIntegralItem(new Int16Array(buffer), 2),
+ (1n << 16n) - 1n,
+ );
+ });
+});
+
+describe("get32BitFloatingPointItem", () => {
+ it("[[Call]] gets the item", () => {
+ const buffer = new ArrayBuffer(12);
+ const view = new DataView(buffer);
+ view.setFloat32(0, NaN);
+ view.setFloat32(4, -Infinity);
+ view.setFloat32(8, -0);
+ assertStrictEquals(get32BitFloatingPointItem(buffer, 0), NaN);
+ assertStrictEquals(
+ get32BitFloatingPointItem(buffer, 4),
+ -Infinity,
+ );
+ assertStrictEquals(get32BitFloatingPointItem(buffer, 8), -0);
+ assertStrictEquals(
+ get32BitFloatingPointItem(new DataView(buffer), 4),
+ -Infinity,
+ );
+ assertStrictEquals(
+ get32BitFloatingPointItem(new Uint32Array(buffer), 4),
+ -Infinity,
+ );
+ });
+});
+
+describe("get32BitSignedIntegralItem", () => {
+ it("[[Call]] gets the item", () => {
+ const buffer = Int8Array.from(
+ [0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0],
+ ).buffer;
+ assertStrictEquals(get32BitSignedIntegralItem(buffer, 4), -1n);
+ assertStrictEquals(
+ get32BitSignedIntegralItem(new DataView(buffer), 4),
+ -1n,
+ );
+ assertStrictEquals(
+ get32BitSignedIntegralItem(new Uint32Array(buffer), 4),
+ -1n,
+ );
+ });
+});
+
+describe("get32BitUnsignedIntegralItem", () => {
+ it("[[Call]] gets the item", () => {
+ const buffer = Int8Array.from(
+ [0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0],
+ ).buffer;
+ assertStrictEquals(
+ get32BitUnsignedIntegralItem(buffer, 4),
+ (1n << 32n) - 1n,
+ );
+ assertStrictEquals(
+ get32BitUnsignedIntegralItem(new DataView(buffer), 4),
+ (1n << 32n) - 1n,
+ );
+ assertStrictEquals(
+ get32BitUnsignedIntegralItem(new Int32Array(buffer), 4),
+ (1n << 32n) - 1n,
+ );
+ });
+});
+
+describe("get64BitFloatingPointItem", () => {
+ it("[[Call]] gets the item", () => {
+ const buffer = new ArrayBuffer(24);
+ const view = new DataView(buffer);
+ view.setFloat64(0, NaN);
+ view.setFloat64(8, -Infinity);
+ view.setFloat64(16, -0);
+ assertStrictEquals(get64BitFloatingPointItem(buffer, 0), NaN);
+ assertStrictEquals(
+ get64BitFloatingPointItem(buffer, 8),
+ -Infinity,
+ );
+ assertStrictEquals(get64BitFloatingPointItem(buffer, 16), -0);
+ assertStrictEquals(
+ get64BitFloatingPointItem(new DataView(buffer), 8),
+ -Infinity,
+ );
+ assertStrictEquals(
+ get64BitFloatingPointItem(new BigUint64Array(buffer), 8),
+ -Infinity,
+ );
+ });
+});
+
+describe("get64BitSignedIntegralItem", () => {
+ it("[[Call]] gets the item", () => {
+ const buffer = Int8Array.from(
+ [0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1],
+ ).buffer;
+ assertStrictEquals(get64BitSignedIntegralItem(buffer, 8), -1n);
+ assertStrictEquals(
+ get64BitSignedIntegralItem(new DataView(buffer), 8),
+ -1n,
+ );
+ assertStrictEquals(
+ get64BitSignedIntegralItem(new BigUint64Array(buffer), 8),
+ -1n,
+ );
+ });
+});
+
+describe("get64BitUnsignedIntegralItem", () => {
+ it("[[Call]] gets the item", () => {
+ const buffer = Int8Array.from(
+ [0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1],
+ ).buffer;
+ assertStrictEquals(
+ get64BitUnsignedIntegralItem(buffer, 8),
+ (1n << 64n) - 1n,
+ );
+ assertStrictEquals(
+ get64BitUnsignedIntegralItem(new DataView(buffer), 8),
+ (1n << 64n) - 1n,
+ );
+ assertStrictEquals(
+ get64BitUnsignedIntegralItem(new BigInt64Array(buffer), 8),
+ (1n << 64n) - 1n,
+ );
+ });
+});
+
+describe("isArrayBuffer", () => {
+ it("[[Call]] returns true for array buffers", () => {
+ assertStrictEquals(
+ isArrayBuffer(new ArrayBuffer()),
+ true,
+ );
+ assertStrictEquals(
+ isArrayBuffer(new SharedArrayBuffer()),
+ true,
+ );
+ });
+
+ it("[[Call]] returns false for others", () => {
+ [
+ undefined,
+ null,
+ true,
+ Symbol(),
+ 27,
+ 98n,
+ {},
+ [],
+ () => {},
+ new Proxy({}, {}),
+ "string",
+ new DataView(new ArrayBuffer()),
+ new Uint8Array(),
+ ].forEach((value) =>
+ assertStrictEquals(isArrayBuffer(value), false)
+ );
+ });
+});
+
+describe("isArrayBufferView", () => {
+ it("[[Call]] returns true for data views", () => {
+ assertStrictEquals(
+ isArrayBufferView(new DataView(new ArrayBuffer())),
+ true,
+ );
+ });
+
+ it("[[Call]] returns true for typed arrays", () => {
+ assertStrictEquals(
+ isArrayBufferView(new Uint8ClampedArray()),
+ true,
);
+ assertStrictEquals(isArrayBufferView(new BigInt64Array()), true);
+ });
+
+ it("[[Call]] returns false for others", () => {
+ [
+ undefined,
+ null,
+ true,
+ Symbol(),
+ 27,
+ 98n,
+ {},
+ [],
+ () => {},
+ new Proxy({}, {}),
+ "string",
+ new ArrayBuffer(),
+ new SharedArrayBuffer(),
+ ].forEach((value) =>
+ assertStrictEquals(isArrayBufferView(value), false)
+ );
+ });
+});
+
+describe("isBase16", () => {
+ it("[[Call]] returns true for base64 strings", () => {
+ for (const { base16 } of data.values()) {
+ assertStrictEquals(isBase16(base16), true);
+ assertStrictEquals(isBase16(base16.toLowerCase()), true);
+ }
+ });
+
+ it("[[Call]] returns false for others", () => {
+ [
+ undefined,
+ null,
+ true,
+ Symbol(),
+ 27,
+ 98n,
+ {},
+ [],
+ () => {},
+ new Proxy({}, {}),
+ "abc_",
+ "a",
+ "abc",
+ "abcg",
+ ].forEach((value) => assertStrictEquals(isBase16(value), false));
+ });
+});
+
+describe("isBase32", () => {
+ it("[[Call]] returns true for base32 strings", () => {
+ for (const { base32 } of data.values()) {
+ assertStrictEquals(isBase32(base32), true);
+ assertStrictEquals(isBase32(base32.toLowerCase()), true);
+ }
+ });
+
+ it("[[Call]] returns false for others", () => {
+ [
+ undefined,
+ null,
+ true,
+ Symbol(),
+ 27,
+ 98n,
+ {},
+ [],
+ () => {},
+ new Proxy({}, {}),
+ "ABC1",
+ "A=======",
+ "ABCDEFGHI",
+ ].forEach((value) => assertStrictEquals(isBase32(value), false));
});
});
describe("isBase64", () => {
it("[[Call]] returns true for base64 strings", () => {
- Object.keys(base64s).forEach((key) => assert(isBase64(key)));
+ for (const { base64 } of data.values()) {
+ assertStrictEquals(isBase64(base64), true);
+ }
});
it("[[Call]] returns false for others", () => {
"abc_",
"a",
"abc==",
- ].forEach((value) => assert(!isBase64(value)));
+ ].forEach((value) => assertStrictEquals(isBase64(value), false));
});
});
describe("isFilenameSafeBase64", () => {
it("[[Call]] returns true for filename‐safe base64 strings", () => {
- Object.keys(base64s).forEach((key) =>
- assert(
- isFilenameSafeBase64(key.replace("+", "-").replace("/", "_")),
- )
- );
+ for (const { base64 } of data.values()) {
+ assertStrictEquals(
+ isFilenameSafeBase64(
+ base64.replace("+", "-").replace("/", "_"),
+ ),
+ true,
+ );
+ }
});
it("[[Call]] returns false for others", () => {
"abc/",
"a",
"abc==",
- ].forEach((value) => assert(!isFilenameSafeBase64(value)));
+ ].forEach((value) =>
+ assertStrictEquals(isFilenameSafeBase64(value), false)
+ );
+ });
+});
+
+describe("isSharedArrayBuffer", () => {
+ it("[[Call]] returns true for shared array buffers", () => {
+ assertStrictEquals(
+ isSharedArrayBuffer(new SharedArrayBuffer()),
+ true,
+ );
+ });
+
+ it("[[Call]] returns false for others", () => {
+ [
+ undefined,
+ null,
+ true,
+ Symbol(),
+ 27,
+ 98n,
+ {},
+ [],
+ () => {},
+ new Proxy({}, {}),
+ "string",
+ new ArrayBuffer(),
+ new DataView(new ArrayBuffer()),
+ new Uint8Array(),
+ ].forEach((value) =>
+ assertStrictEquals(isSharedArrayBuffer(value), false)
+ );
+ });
+});
+
+describe("isTypedArray", () => {
+ it("[[Call]] returns true for typed arrays", () => {
+ assertStrictEquals(
+ isTypedArray(new Uint8Array()),
+ true,
+ );
+ assertStrictEquals(
+ isTypedArray(new BigInt64Array()),
+ true,
+ );
+ });
+
+ it("[[Call]] returns false for others", () => {
+ [
+ undefined,
+ null,
+ true,
+ Symbol(),
+ 27,
+ 98n,
+ {},
+ [],
+ () => {},
+ new Proxy({}, {}),
+ "string",
+ new ArrayBuffer(),
+ new SharedArrayBuffer(),
+ new DataView(new ArrayBuffer()),
+ ].forEach((value) =>
+ assertStrictEquals(isTypedArray(value), false)
+ );
+ });
+});
+
+describe("isWRMGBase32", () => {
+ it("[[Call]] returns true for W·R·M·G base32 strings", () => {
+ for (const { wrmg } of data.values()) {
+ assertStrictEquals(isWRMGBase32(wrmg), true);
+ assertStrictEquals(isWRMGBase32(wrmg.toLowerCase()), true);
+ assertStrictEquals(isWRMGBase32(`--${wrmg}--`), true);
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/1/gu, "I")),
+ true,
+ );
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/1/gu, "L")),
+ true,
+ );
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/0/gu, "O")),
+ true,
+ );
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/1/gu, "i")),
+ true,
+ );
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/1/gu, "l")),
+ true,
+ );
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/0/gu, "o")),
+ true,
+ );
+ assertStrictEquals(
+ isWRMGBase32(wrmg.replaceAll(/./gu, ($) => {
+ const rand = Math.random();
+ return rand < 0.25
+ ? $
+ : rand < 0.5
+ ? `-${$}`
+ : rand < 0.75
+ ? `${$}-`
+ : `-${$}-`;
+ })),
+ true,
+ );
+ }
+ });
+
+ it("[[Call]] returns false for others", () => {
+ [
+ undefined,
+ null,
+ true,
+ Symbol(),
+ 27,
+ 98n,
+ {},
+ [],
+ () => {},
+ new Proxy({}, {}),
+ "ABCU",
+ "A",
+ "ABCDEFGH1",
+ ].forEach((value) =>
+ assertStrictEquals(isWRMGBase32(value), false)
+ );
+ });
+});
+
+describe("set8BitIntegralItem", () => {
+ it("[[Call]] sets the item", () => {
+ const buffer = new ArrayBuffer(3);
+ set8BitIntegralItem(buffer, 1, -1n);
+ set8BitIntegralItem(buffer, 2, (1 << 8) - 1);
+ assertEquals(
+ new Int8Array(buffer),
+ Int8Array.from([0, -1, -1]),
+ );
+ });
+});
+
+describe("set16BitIntegralItem", () => {
+ it("[[Call]] sets the item", () => {
+ const buffer = new ArrayBuffer(6);
+ set16BitIntegralItem(buffer, 2, -1n);
+ set16BitIntegralItem(buffer, 4, (1 << 16) - 1);
+ assertEquals(
+ new Int8Array(buffer),
+ Int8Array.from([0, 0, -1, -1, -1, -1]),
+ );
+ });
+});
+
+describe("set32BitFloatingPointItem", () => {
+ it("[[Call]] sets the item", () => {
+ const buffer = new ArrayBuffer(12);
+ const expected = new ArrayBuffer(12);
+ const view = new DataView(expected);
+ view.setFloat32(0, NaN);
+ set32BitFloatingPointItem(buffer, 0, NaN);
+ view.setFloat32(4, -Infinity);
+ set32BitFloatingPointItem(buffer, 4, -Infinity);
+ view.setFloat32(8, -0);
+ set32BitFloatingPointItem(buffer, 8, -0);
+ assertEquals(
+ new Uint8Array(buffer),
+ new Uint8Array(expected),
+ );
+ });
+});
+
+describe("set32BitIntegralItem", () => {
+ it("[[Call]] sets the item", () => {
+ const buffer = new ArrayBuffer(12);
+ set32BitIntegralItem(buffer, 4, -1n);
+ set32BitIntegralItem(buffer, 8, -1 >>> 0);
+ assertEquals(
+ new Int8Array(buffer),
+ Int8Array.from([0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1]),
+ );
+ });
+});
+
+describe("set64BitFloatingPointItem", () => {
+ it("[[Call]] sets the item", () => {
+ const buffer = new ArrayBuffer(24);
+ const expected = new ArrayBuffer(24);
+ const view = new DataView(expected);
+ view.setFloat64(0, NaN);
+ set64BitFloatingPointItem(buffer, 0, NaN);
+ view.setFloat64(4, -Infinity);
+ set64BitFloatingPointItem(buffer, 4, -Infinity);
+ view.setFloat64(8, -0);
+ set64BitFloatingPointItem(buffer, 8, -0);
+ assertEquals(
+ new Uint8Array(buffer),
+ new Uint8Array(expected),
+ );
+ });
+});
+
+describe("set64BitIntegralItem", () => {
+ it("[[Call]] sets the item", () => {
+ const buffer = new ArrayBuffer(12);
+ set64BitIntegralItem(buffer, 4, -1n);
+ assertEquals(
+ new Int8Array(buffer),
+ Int8Array.from([0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1]),
+ );
+ });
+});
+
+describe("toArrayBuffer", () => {
+ it("[[Call]] returns the argument for array buffers", () => {
+ const buffer = new ArrayBuffer();
+ assertStrictEquals(toArrayBuffer(buffer), buffer);
+ });
+
+ it("[[Call]] returns the buffer for data views", () => {
+ const src = Uint8Array.from([2, 3, 1]);
+ const buffer = toArrayBuffer(new DataView(src.buffer));
+ assert(buffer instanceof ArrayBuffer);
+ assertEquals(new Uint8Array(buffer), src);
+ });
+
+ it("[[Call]] returns the buffer for typed arrays", () => {
+ const src = Uint8Array.from([2, 3, 1]);
+ const buffer = toArrayBuffer(src);
+ assert(buffer instanceof ArrayBuffer);
+ assertEquals(new Uint8Array(buffer), src);
+ });
+
+ it("[[Call]] throws for others", () => {
+ [
+ undefined,
+ null,
+ true,
+ Symbol(),
+ 27,
+ 98n,
+ {},
+ [],
+ () => {},
+ new Proxy({}, {}),
+ "string",
+ ].forEach((value) =>
+ assertThrows(() => {
+ toArrayBuffer(value);
+ })
+ );
+ });
+});
+
+describe("wrmgBase32Binary", () => {
+ it("[[Call]] returns the correct data", () => {
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("")),
+ new Uint8Array([]),
+ "<empty>",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("01H00R80EC06A01P00T0")),
+ Uint8Array.from(
+ "\u{0}b\u{0}a\u{0}s\u{0}e\u{0}6\u{0}4",
+ ($) => $.charCodeAt(0),
+ ),
+ "01H00R80EC06A01P00T0",
+ );
+ assertEquals(
+ new Uint16Array(wrmgBase32Binary("8ZT0")),
+ new Uint16Array([62535]),
+ "8ZT0",
+ );
+ assertEquals(
+ new Uint8ClampedArray(wrmgBase32Binary("9D4M4J8")),
+ new Uint8ClampedArray([75, 73, 66, 73]),
+ "9D4M4J8",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("C9GQ6S9P6G")),
+ new Uint8Array([98, 97, 115, 101, 54, 52]),
+ "C9GQ6S9P6G",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("2KXSR0YSFR")),
+ new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9, 0x7E]),
+ "2KXSR0YSFR",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("2KXSR0YS")),
+ new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9]),
+ "2KXSR0YS",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("2KXSR0R")),
+ new Uint8Array([0x14, 0xFB, 0x9C, 0x03]),
+ "2KXSR0R",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("50")),
+ new Uint8Array([0x28]),
+ "50",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("TR")),
+ new Uint8Array([0xD6]),
+ "TR",
+ );
+ assertEquals(
+ new Uint16Array(wrmgBase32Binary("TVW0")),
+ new Uint16Array([0xF8D6]),
+ "TVW0",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("TVW00")),
+ new Uint8Array([0xD6, 0xF8, 0x00]),
+ "TVW00",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("TVW10")),
+ new Uint8Array([0xD6, 0xF8, 0x10]),
+ "TVW10",
+ );
+ assertEquals(
+ new Uint32Array(wrmgBase32Binary("TVW1230")),
+ new Uint32Array([0x0C11F8D6]),
+ "TVW1230",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("TVW12340")),
+ new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]),
+ "TVW12340",
+ );
+ assertEquals(
+ new Uint16Array(wrmgBase32Binary("TVW1234560")),
+ new Uint16Array([0xF8D6, 0x0C11, 0x3085]),
+ "TVW1234560",
+ );
+ });
+
+ it("[[Call]] is case‐insensitive", () => {
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("tVw12340")),
+ new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]),
+ "tVw12340",
+ );
+ });
+
+ it("[[Call]] casts I, L & O", () => {
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("TVWI234O")),
+ new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]),
+ "TVWI234O",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("TVWi234o")),
+ new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]),
+ "TVWi234o",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("TVWL234O")),
+ new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]),
+ "TVWL234O",
+ );
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("TVWl234o")),
+ new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]),
+ "TVWl234o",
+ );
+ });
+
+ it("[[Call]] ignores hyphens", () => {
+ assertEquals(
+ new Uint8Array(wrmgBase32Binary("--TVW---123-40-----")),
+ new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]),
+ "--TVW---123-40-----",
+ );
+ });
+
+ it("[[Call]] throws when provided with an invalid character", () => {
+ assertThrows(() => wrmgBase32Binary("ABCu"));
+ assertThrows(() => wrmgBase32Binary("ABCU"));
+ assertThrows(() => wrmgBase32Binary("ABC="));
+ });
+
+ it("[[Call]] throws when provided with a length with a remainder of 1, 3 ∣ 6 when divided by 8", () => {
+ assertThrows(() => base32Binary("TVW123400"));
+ assertThrows(() => base32Binary("TVW123400======="));
+ assertThrows(() => base32Binary("M78"));
+ assertThrows(() => base32Binary("M78M93"));
+ });
+
+ it("[[Call]] throws when provided with a length with a remainder of 1 when divided by 4", () => {
+ assertThrows(() => wrmgBase32Binary("234BCDEAA"));
+ assertThrows(() => wrmgBase32Binary("2-34-B--CD-EA-A-"));
+ });
+});
+
+describe("wrmgBase32String", () => {
+ it("[[Call]] returns the correct string", () => {
+ for (const [source, { wrmg }] of data) {
+ assertStrictEquals(wrmgBase32String(source), wrmg);
+ }
});
});