X-Git-Url: https://git.ladys.computer/Pisces/blobdiff_plain/d4fe7e59e1444b5e29a71b80d89a8ad5aa1158bd..HEAD:/binary.test.js diff --git a/binary.test.js b/binary.test.js old mode 100755 new mode 100644 index f3c8317..98f441a --- a/binary.test.js +++ b/binary.test.js @@ -16,6 +16,7 @@ import { it, } from "./dev-deps.js"; import { + arrayBufferSlice, base16Binary, base16String, base32Binary, @@ -24,11 +25,32 @@ import { 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"; @@ -137,6 +159,45 @@ const data = new Map([ }], ]); +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( @@ -356,9 +417,11 @@ describe("base32Binary", () => { assertThrows(() => base32Binary("CT3ZYAY==")); }); - it("[[Call]] throws when provided with a length with a remainder of 1 when divided by 4", () => { + 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")); }); }); @@ -576,11 +639,266 @@ describe("filenameSafeBase64String", () => { }); }); +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()) { - assert(isBase16(base16)); - assert(isBase16(base16.toLowerCase())); + assertStrictEquals(isBase16(base16), true); + assertStrictEquals(isBase16(base16.toLowerCase()), true); } }); @@ -600,15 +918,15 @@ describe("isBase16", () => { "a", "abc", "abcg", - ].forEach((value) => assert(!isBase16(value))); + ].forEach((value) => assertStrictEquals(isBase16(value), false)); }); }); describe("isBase32", () => { it("[[Call]] returns true for base32 strings", () => { for (const { base32 } of data.values()) { - assert(isBase32(base32)); - assert(isBase32(base32.toLowerCase())); + assertStrictEquals(isBase32(base32), true); + assertStrictEquals(isBase32(base32.toLowerCase()), true); } }); @@ -627,14 +945,14 @@ describe("isBase32", () => { "ABC1", "A=======", "ABCDEFGHI", - ].forEach((value) => assert(!isBase32(value))); + ].forEach((value) => assertStrictEquals(isBase32(value), false)); }); }); describe("isBase64", () => { it("[[Call]] returns true for base64 strings", () => { for (const { base64 } of data.values()) { - assert(isBase64(base64)); + assertStrictEquals(isBase64(base64), true); } }); @@ -653,17 +971,18 @@ describe("isBase64", () => { "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", () => { for (const { base64 } of data.values()) { - assert( + assertStrictEquals( isFilenameSafeBase64( base64.replace("+", "-").replace("/", "_"), ), + true, ); } }); @@ -683,32 +1002,119 @@ describe("isFilenameSafeBase64", () => { "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()) { - assert(isWRMGBase32(wrmg)); - assert(isWRMGBase32(wrmg.toLowerCase())); - assert(isWRMGBase32(`--${wrmg}--`)); - assert(isWRMGBase32(wrmg.replaceAll(/1/gu, "I"))); - assert(isWRMGBase32(wrmg.replaceAll(/1/gu, "L"))); - assert(isWRMGBase32(wrmg.replaceAll(/0/gu, "O"))); - assert(isWRMGBase32(wrmg.replaceAll(/1/gu, "i"))); - assert(isWRMGBase32(wrmg.replaceAll(/1/gu, "l"))); - assert(isWRMGBase32(wrmg.replaceAll(/0/gu, "o"))); - assert(isWRMGBase32(wrmg.replaceAll(/./gu, ($) => { - const rand = Math.random(); - return rand < 0.25 - ? $ - : rand < 0.5 - ? `-${$}` - : rand < 0.75 - ? `${$}-` - : `-${$}-`; - }))); + 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, + ); } }); @@ -727,7 +1133,133 @@ describe("isWRMGBase32", () => { "ABCU", "A", "ABCDEFGH1", - ].forEach((value) => assert(!isWRMGBase32(value))); + ].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); + }) + ); }); }); @@ -863,6 +1395,13 @@ describe("wrmgBase32Binary", () => { 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-"));