it,
} from "./dev-deps.js";
import {
+ base16Binary,
+ base16String,
base64Binary,
base64String,
filenameSafeBase64Binary,
filenameSafeBase64String,
+ isBase16,
isBase64,
isFilenameSafeBase64,
} from "./binary.js";
// These tests assume a LITTLE‐ENDIAN environment.
const data = new Map([
["", {
+ base16: "",
base64: "",
}],
["base64", {
+ base16: "006200610073006500360034",
base64: "AGIAYQBzAGUANgA0",
}],
[new Uint16Array([62535]), {
+ base16: "47F4",
base64: "R/Q=",
}],
[new Uint8ClampedArray([75, 73, 66, 73]).buffer, {
+ base16: "4B494249",
base64: "S0lCSQ==",
}],
[new DataView(new Uint8Array([98, 97, 115, 101, 54, 52]).buffer), {
+ base16: "626173653634",
base64: "YmFzZTY0",
}],
// The following three examples are from RFC 3548.
[new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9, 0x7E]), {
+ base16: "14FB9C03D97E",
base64: "FPucA9l+",
}],
[new Uint8Array([0x14, 0xFB, 0x9C, 0x03, 0xD9]), {
+ base16: "14FB9C03D9",
base64: "FPucA9k=",
}],
[new Uint8Array([0x14, 0xFB, 0x9C, 0x03]), {
+ base16: "14FB9C03",
base64: "FPucAw==",
}],
// The following examples are from the Ruby base32 gem.
[new Uint8Array([0x28]), {
+ base16: "28",
base64: "KA==",
}],
[new Uint8Array([0xD6]), {
+ base16: "D6",
base64: "1g==",
}],
[new Uint16Array([0xF8D6]), {
+ base16: "D6F8",
base64: "1vg=",
}],
[new Uint8Array([0xD6, 0xF8, 0x00]), {
+ base16: "D6F800",
base64: "1vgA",
}],
[new Uint8Array([0xD6, 0xF8, 0x10]), {
+ base16: "D6F810",
base64: "1vgQ",
}],
[new Uint32Array([0x0C11F8D6]), {
+ base16: "D6F8110C",
base64: "1vgRDA==",
}],
[new Uint8Array([0xD6, 0xF8, 0x11, 0x0C, 0x80]), {
+ base16: "D6F8110C80",
base64: "1vgRDIA=",
}],
[new Uint16Array([0xF8D6, 0x0C11, 0x3085]), {
+ base16: "D6F8110C8530",
base64: "1vgRDIUw",
}],
]);
+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("base64Binary", () => {
it("[[Call]] returns the correct data", () => {
assertEquals(
});
});
+describe("isBase16", () => {
+ it("[[Call]] returns true for base64 strings", () => {
+ for (const { base16 } of data.values()) {
+ assert(isBase16(base16));
+ assert(isBase16(base16.toLowerCase()));
+ }
+ });
+
+ it("[[Call]] returns false for others", () => {
+ [
+ undefined,
+ null,
+ true,
+ Symbol(),
+ 27,
+ 98n,
+ {},
+ [],
+ () => {},
+ new Proxy({}, {}),
+ "abc_",
+ "a",
+ "abc",
+ "abcg",
+ ].forEach((value) => assert(!isBase16(value)));
+ });
+});
+
describe("isBase64", () => {
it("[[Call]] returns true for base64 strings", () => {
for (const { base64 } of data.values()) {