// Copyright (C) 2016 Dmitry Chestnykh // MIT License. See LICENSE file for details. import { describe, expect, it } from 'vitest'; import { readInt16BE, readInt16LE, readInt32BE, readInt32LE, readInt64BE, readInt64LE, readUint16BE, writeUint16BE, readUint16LE, writeUint16LE, readUint32BE, writeUint32BE, readUint32LE, writeUint32LE, readUint64BE, writeUint64BE, readUint64LE, writeUint64LE, readUintLE, writeUintLE, readUintBE, writeUintBE, readFloat32BE, writeFloat32BE, readFloat64BE, writeFloat64BE, readFloat32LE, writeFloat32LE, readFloat64LE, writeFloat64LE } from "./binary.js"; const int16BEVectors: [number, number[]][] = [ [0, [0, 0]], [1, [0, 1]], [255, [0, 255]], [-2, [255, 254]], [-1, [255, 255]], [32767, [127, 255]] ]; const int16LEVectors = int16BEVectors.map(v => [v[0], (v[1] as number[]).slice().reverse()] ) as [number, number[]][]; describe("readInt16BE", () => { it("should read correct value", () => { int16BEVectors.forEach(v => { const buf = new Uint8Array(v[1] as number[]); expect(readInt16BE(buf)).toEqual(v[0]); }); }); }); describe("readInt16LE", () => { it("should read correct value", () => { int16LEVectors.forEach(v => { const buf = new Uint8Array(v[1] as number[]); expect(readInt16LE(buf)).toEqual(v[0]); }); }); }); const uint16BEVectors: [number, number[]][] = [ [0, [0, 0]], [1, [0, 1]], [255, [0, 255]], [256, [1, 0]], [65535, [255, 255]] ]; const uint16LEVectors = uint16BEVectors.map(v => [v[0], (v[1] as number[]).slice().reverse()] ) as [number, number[]][]; describe("readUint16BE", () => { it("should read correct value", () => { uint16BEVectors.forEach(v => { const buf = new Uint8Array(v[1] as number[]); expect(readUint16BE(buf)).toEqual(v[0]); }); }); it("should read from correct offset", () => { const orig = new Uint8Array([0, 1, 2]); const value = readUint16BE(orig, 1); expect(value).toBe(258); }); }); describe("writeUint16BE", () => { it("should write correct value", () => { uint16BEVectors.forEach(v => { const buf = new Uint8Array(2); const good = new Uint8Array(v[1] as number[]); const value = v[0] as number; expect(writeUint16BE(value, buf)).toEqual(good); }); }); it("should allocate new array if not given", () => { expect(Object.prototype.toString.call(writeUint16BE(1))).toBe("[object Uint8Array]"); }); it("should write to correct offset", () => { const orig = new Uint8Array([0, 1, 2]); const result = writeUint16BE(258, new Uint8Array(3), 1); expect(result).toEqual(orig); }); }); describe("readUint16LE", () => { it("should read correct value", () => { uint16LEVectors.forEach(v => { const buf = new Uint8Array(v[1] as number[]); expect(readUint16LE(buf)).toEqual(v[0]); }); }); it("should read from correct offset", () => { const orig = new Uint8Array([0, 1, 2]); const value = readUint16LE(orig, 1); expect(value).toBe(513); }); }); describe("writeUint16LE", () => { it("should write correct value", () => { uint16LEVectors.forEach(v => { const buf = new Uint8Array(2); const good = new Uint8Array(v[1] as number[]); const value = v[0] as number; expect(writeUint16LE(value, buf)).toEqual(good); }); }); it("should allocate new array if not given", () => { expect(Object.prototype.toString.call(writeUint16LE(1))).toBe("[object Uint8Array]"); }); it("should write to correct offset", () => { const orig = new Uint8Array([0, 1, 2]); const result = writeUint16LE(513, new Uint8Array(3), 1); expect(result).toEqual(orig); }); }); const int32BEVectors: [number, number[]][] = [ [0, [0, 0, 0, 0]], [1, [0, 0, 0, 1]], [255, [0, 0, 0, 255]], [-2, [255, 255, 255, 254]], [-1, [255, 255, 255, 255]], [32767, [0, 0, 127, 255]], [2147483647, [127, 255, 255, 255]], [-2147483647, [128, 0, 0, 1]] ]; const int32LEVectors = int32BEVectors.map(v => [v[0], (v[1] as number[]).slice().reverse()] ) as [number, number[]][]; describe("readInt32BE", () => { it("should read correct value", () => { int32BEVectors.forEach(v => { const buf = new Uint8Array(v[1] as number[]); expect(readInt32BE(buf)).toEqual(v[0]); }); }); }); describe("readInt32LE", () => { it("should read correct value", () => { int32LEVectors.forEach(v => { const buf = new Uint8Array(v[1] as number[]); expect(readInt32LE(buf)).toEqual(v[0]); }); }); }); const uint32BEVectors: [number, number[]][] = [ [0, [0, 0, 0, 0]], [1, [0, 0, 0, 1]], [255, [0, 0, 0, 255]], [256, [0, 0, 1, 0]], [65535, [0, 0, 255, 255]], [16777215, [0, 255, 255, 255]], [2147483647, [127, 255, 255, 255]], [4294901660, [255, 254, 255, 156]], [4294967295, [255, 255, 255, 255]], ]; const uint32LEVectors = uint32BEVectors.map(v => [v[0], (v[1] as number[]).slice().reverse()] ) as [number, number[]][]; describe("readUint32BE", () => { it("should read correct value", () => { uint32BEVectors.forEach(v => { const buf = new Uint8Array(v[1] as number[]); expect(readUint32BE(buf)).toEqual(v[0]); }); }); it("should read from correct offset", () => { const orig = new Uint8Array([0, 1, 2, 3, 4]); const value = readUint32BE(orig, 1); expect(value).toBe(16909060); }); }); describe("writeUint32BE", () => { it("should write correct value", () => { uint32BEVectors.forEach(v => { const buf = new Uint8Array(4); const good = new Uint8Array(v[1] as number[]); const value = v[0] as number; expect(writeUint32BE(value, buf)).toEqual(good); }); }); it("should allocate new array if not given", () => { expect(Object.prototype.toString.call(writeUint32BE(1))).toBe("[object Uint8Array]"); }); it("should write to correct offset", () => { const orig = new Uint8Array([0, 1, 2, 3, 4]); const result = writeUint32BE(16909060, new Uint8Array(5), 1); expect(result).toEqual(orig); }); }); describe("readUint32LE", () => { it("should read correct value", () => { uint32LEVectors.forEach(v => { const buf = new Uint8Array(v[1] as number[]); expect(readUint32LE(buf)).toEqual(v[0]); }); }); it("should read from correct offset", () => { const orig = new Uint8Array([0, 1, 2, 3, 4]); const value = readUint32LE(orig, 1); expect(value).toBe(67305985); }); }); describe("writeUint32LE", () => { it("should write correct value", () => { uint32LEVectors.forEach(v => { const buf = new Uint8Array(4); const good = new Uint8Array(v[1] as number[]); const value = v[0] as number; expect(writeUint32LE(value, buf)).toEqual(good); }); }); it("should allocate new array if not given", () => { expect(Object.prototype.toString.call(writeUint32LE(1))).toBe("[object Uint8Array]"); }); it("should write to correct offset", () => { const orig = new Uint8Array([0, 1, 2, 3, 4]); const result = writeUint32LE(67305985, new Uint8Array(5), 1); expect(result).toEqual(orig); }); }); const int64BEVectors: [number, number[]][] = [ [0, [0, 0, 0, 0, 0, 0, 0, 0]], [1, [0, 0, 0, 0, 0, 0, 0, 1]], [255, [0, 0, 0, 0, 0, 0, 0, 255]], [256, [0, 0, 0, 0, 0, 0, 1, 0]], [65535, [0, 0, 0, 0, 0, 0, 255, 255]], [16777215, [0, 0, 0, 0, 0, 255, 255, 255]], [2147483647, [0, 0, 0, 0, 127, 255, 255, 255]], [4294901660, [0, 0, 0, 0, 255, 254, 255, 156]], [4294967295, [0, 0, 0, 0, 255, 255, 255, 255]], [2146252406, [0, 0, 0, 0, 127, 237, 54, 118]], [2147483648, [0, 0, 0, 0, 128, 0, 0, 0]], [4294967296, [0, 0, 0, 1, 0, 0, 0, 0]], [4295450643, [0, 0, 0, 1, 0, 7, 96, 19]], [8589934592, [0, 0, 0, 2, 0, 0, 0, 0]], [35184372088610, [0, 0, 31, 255, 255, 255, 255, 34]], [-35184372088610, [255, 255, 224, 0, 0, 0, 0, 222]], [140737488355326, [0, 0, 127, 255, 255, 255, 255, 254]], [9007199254740991, [0, 31, 255, 255, 255, 255, 255, 255]] ]; const int64LEVectors = int64BEVectors.map(v => [v[0], (v[1] as number[]).slice().reverse()] ) as [number, number[]][]; describe("readInt64BE", () => { it("should read correct value", () => { int64BEVectors.forEach(v => { const buf = new Uint8Array(v[1] as number[]); expect(readInt64BE(buf)).toEqual(v[0]); }); }); }); describe("readInt64LE", () => { it("should read correct value", () => { int64LEVectors.forEach(v => { const buf = new Uint8Array(v[1] as number[]); expect(readInt64LE(buf)).toEqual(v[0]); }); }); }); const uint64BEVectors: [number, number[]][] = [ [0, [0, 0, 0, 0, 0, 0, 0, 0]], [1, [0, 0, 0, 0, 0, 0, 0, 1]], [255, [0, 0, 0, 0, 0, 0, 0, 255]], [256, [0, 0, 0, 0, 0, 0, 1, 0]], [65535, [0, 0, 0, 0, 0, 0, 255, 255]], [16777215, [0, 0, 0, 0, 0, 255, 255, 255]], [2147483647, [0, 0, 0, 0, 127, 255, 255, 255]], [4294901660, [0, 0, 0, 0, 255, 254, 255, 156]], [4294967295, [0, 0, 0, 0, 255, 255, 255, 255]], [2146252406, [0, 0, 0, 0, 127, 237, 54, 118]], [2147483648, [0, 0, 0, 0, 128, 0, 0, 0]], [4294967296, [0, 0, 0, 1, 0, 0, 0, 0]], [4295450643, [0, 0, 0, 1, 0, 7, 96, 19]], [8589934592, [0, 0, 0, 2, 0, 0, 0, 0]], [35184372088610, [0, 0, 31, 255, 255, 255, 255, 34]], [281474976710655, [0, 0, 255, 255, 255, 255, 255, 255]], [140737488355326, [0, 0, 127, 255, 255, 255, 255, 254]], [9007199254740991, [0, 31, 255, 255, 255, 255, 255, 255]] ]; const uint64LEVectors = uint64BEVectors.map(v => [v[0], (v[1] as number[]).slice().reverse()] ) as [number, number[]][]; describe("readUint64BE", () => { it("should read correct value", () => { uint64BEVectors.forEach(v => { const buf = new Uint8Array(v[1] as number[]); expect(readUint64BE(buf)).toEqual(v[0]); }); }); it("should read from correct offset", () => { const orig = new Uint8Array([0, 0, 1, 2, 3, 4, 5, 6, 7]); const value = readUint64BE(orig, 1); expect(value).toBe(283686952306183); }); }); describe("writeUint64BE", () => { it("should write correct value", () => { uint64BEVectors.forEach(v => { const buf = new Uint8Array(8); const good = new Uint8Array(v[1] as number[]); const value = v[0] as number; expect(writeUint64BE(value, buf)).toEqual(good); }); }); it("should allocate new array if not given", () => { expect(Object.prototype.toString.call(writeUint32BE(1))).toBe("[object Uint8Array]"); }); it("should write to correct offset", () => { const orig = new Uint8Array([0, 0, 1, 2, 3, 4, 5, 6, 7]); const result = writeUint64BE(283686952306183, new Uint8Array(9), 1); expect(result).toEqual(orig); }); }); describe("readUint64LE", () => { it("should read correct value", () => { uint64LEVectors.forEach(v => { const buf = new Uint8Array(v[1] as number[]); expect(readUint64LE(buf)).toEqual(v[0]); }); }); it("should read from correct offset", () => { const orig = new Uint8Array([0, 7, 6, 5, 4, 3, 2, 1, 0]); const value = readUint64LE(orig, 1); expect(value).toBe(283686952306183); }); }); describe("writeUint64LE", () => { it("should write correct value", () => { uint64LEVectors.forEach(v => { const buf = new Uint8Array(8); const good = new Uint8Array(v[1] as number[]); const value = v[0] as number; expect(writeUint64LE(value, buf)).toEqual(good); }); }); it("should allocate new array if not given", () => { expect(Object.prototype.toString.call(writeUint32LE(1))).toBe("[object Uint8Array]"); }); it("should write to correct offset", () => { const orig = new Uint8Array([0, 7, 6, 5, 4, 3, 2, 1, 0]); const result = writeUint64LE(283686952306183, new Uint8Array(9), 1); expect(result).toEqual(orig); }); }); describe("readUintLE/writeUintLE", () => { it("should write and read back 32-bit value", () => { const orig = 1234567891; const offset = 2; const wrote = writeUintLE(32, orig, new Uint8Array(6), offset); expect(wrote).toEqual(writeUint32LE(orig, new Uint8Array(6), offset)); expect(readUint32LE(wrote, offset)).toBe(orig); const read = readUintLE(32, wrote, offset); expect(read).toBe(orig); }); it("should write and read back 48-bit value", () => { const orig = Math.pow(2, 48) - 3; const offset = 2; const wrote = writeUintLE(48, orig, new Uint8Array(8), offset); const read = readUintLE(48, wrote, offset); expect(read).toBe(orig); }); it("write throws if given non-integer numbers", () => { expect(() => writeUintLE(56, Math.pow(2, 54))) .toThrowError("writeUintLE value must be an integer"); }); }); describe("readUintBE/writeUintBE", () => { it("should write and read back 32-bit value", () => { const orig = 1234567891; const offset = 2; const wrote = writeUintBE(32, orig, new Uint8Array(6), offset); expect(wrote).toEqual(writeUint32BE(orig, new Uint8Array(6), offset)); expect(readUint32BE(wrote, offset)).toBe(orig); const read = readUintBE(32, wrote, offset); expect(read).toBe(orig); }); it("should write and read back 48-bit value", () => { const orig = Math.pow(2, 48) - 3; const offset = 2; const wrote = writeUintBE(48, orig, new Uint8Array(8), offset); const read = readUintBE(48, wrote, offset); expect(read).toBe(orig); }); it("write throws if given non-integer numbers", () => { expect(() => writeUintBE(56, Math.pow(2, 54))) .toThrowError("writeUintBE value must be an integer"); }); }); describe("readFloat32BE/writeFloat32BE", () => { it("should write and read back value", () => { const orig = 123456.1; const wrote = writeFloat32BE(orig); expect(wrote.length).toBe(4); const read = readFloat32BE(wrote); expect(Math.abs(orig - read)).toBeLessThan(0.1); }); }); describe("readFloat32LE/writeFloat32LE", () => { it("should write and read back value", () => { const orig = 123456.1; const wrote = writeFloat32LE(orig); expect(wrote.length).toBe(4); const read = readFloat32LE(wrote); expect(Math.abs(orig - read)).toBeLessThan(0.1); }); }); describe("readFloat64BE/writeFloat64BE", () => { it("should write and read back value", () => { const orig = 123456891.123; const wrote = writeFloat64BE(orig); expect(wrote.length).toBe(8); const read = readFloat64BE(wrote); expect(read).toBe(orig); }); }); describe("readFloat64LE/writeFloat64LE", () => { it("should write and read back value", () => { const orig = 123456891.123; const wrote = writeFloat64LE(orig); expect(wrote.length).toBe(8); const read = readFloat64LE(wrote); expect(read).toBe(orig); }); });