From 4f73b37cc6978ed66d55fdc540b7e77d8242c885 Mon Sep 17 00:00:00 2001 From: Jason Paulos Date: Fri, 16 Feb 2024 17:10:39 -0500 Subject: [PATCH] Additional int testing --- test/bigint64.test.ts | 304 -------------------------------------- test/codec-bigint.test.ts | 103 +++++++++---- test/encode.test.ts | 32 ++++ 3 files changed, 106 insertions(+), 333 deletions(-) diff --git a/test/bigint64.test.ts b/test/bigint64.test.ts index 73f804a0..b09ccdbf 100644 --- a/test/bigint64.test.ts +++ b/test/bigint64.test.ts @@ -49,307 +49,3 @@ describe("useBigInt64: true", () => { assert.deepStrictEqual(decoded, value); }); }); - -interface TestCase { - input: bigint; - expected: Map; -} - -// declared as a function to delay referencing the BigInt constructor -function BIGINTSPECS(): Record { - return { - ZERO: { - input: BigInt(0), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, 0], - [IntMode.SAFE_NUMBER, 0], - [IntMode.MIXED, 0], - [IntMode.BIGINT, BigInt(0)], - ]), - }, - ONE: { - input: BigInt(1), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, 1], - [IntMode.SAFE_NUMBER, 1], - [IntMode.MIXED, 1], - [IntMode.BIGINT, BigInt(1)], - ]), - }, - MINUS_ONE: { - input: BigInt(-1), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, -1], - [IntMode.SAFE_NUMBER, -1], - [IntMode.MIXED, -1], - [IntMode.BIGINT, BigInt(-1)], - ]), - }, - X_FF: { - input: BigInt(0xff), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, 0xff], - [IntMode.SAFE_NUMBER, 0xff], - [IntMode.MIXED, 0xff], - [IntMode.BIGINT, BigInt(0xff)], - ]), - }, - MINUS_X_FF: { - input: BigInt(-0xff), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, -0xff], - [IntMode.SAFE_NUMBER, -0xff], - [IntMode.MIXED, -0xff], - [IntMode.BIGINT, BigInt(-0xff)], - ]), - }, - INT32_MAX: { - input: BigInt(0x7fffffff), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, 0x7fffffff], - [IntMode.SAFE_NUMBER, 0x7fffffff], - [IntMode.MIXED, 0x7fffffff], - [IntMode.BIGINT, BigInt(0x7fffffff)], - ]), - }, - INT32_MIN: { - input: BigInt(-0x7fffffff - 1), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, -0x7fffffff - 1], - [IntMode.SAFE_NUMBER, -0x7fffffff - 1], - [IntMode.MIXED, -0x7fffffff - 1], - [IntMode.BIGINT, BigInt(-0x7fffffff - 1)], - ]), - }, - MAX_SAFE_INTEGER: { - input: BigInt(Number.MAX_SAFE_INTEGER), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, Number.MAX_SAFE_INTEGER], - [IntMode.SAFE_NUMBER, Number.MAX_SAFE_INTEGER], - [IntMode.MIXED, Number.MAX_SAFE_INTEGER], - [IntMode.BIGINT, BigInt(Number.MAX_SAFE_INTEGER)], - ]), - }, - MAX_SAFE_INTEGER_PLUS_ONE: { - input: BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1), - expected: new Map([ - // exclude IntMode.UNSAFE_NUMBER, behavior will not be exact - [IntMode.SAFE_NUMBER, "error"], - [IntMode.MIXED, BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1)], - [IntMode.BIGINT, BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1)], - ]), - }, - MIN_SAFE_INTEGER: { - input: BigInt(Number.MIN_SAFE_INTEGER), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, Number.MIN_SAFE_INTEGER], - [IntMode.SAFE_NUMBER, Number.MIN_SAFE_INTEGER], - [IntMode.MIXED, Number.MIN_SAFE_INTEGER], - [IntMode.BIGINT, BigInt(Number.MIN_SAFE_INTEGER)], - ]), - }, - MIN_SAFE_INTEGER_MINUS_ONE: { - input: BigInt(Number.MIN_SAFE_INTEGER) - BigInt(1), - expected: new Map([ - // exclude IntMode.UNSAFE_NUMBER, behavior will not be exact - [IntMode.SAFE_NUMBER, "error"], - [IntMode.MIXED, BigInt(Number.MIN_SAFE_INTEGER) - BigInt(1)], - [IntMode.BIGINT, BigInt(Number.MIN_SAFE_INTEGER) - BigInt(1)], - ]), - }, - INT64_MAX: { - input: BigInt("0x7fffffffffffffff"), - expected: new Map([ - // exclude IntMode.UNSAFE_NUMBER, behavior will not be exact - [IntMode.SAFE_NUMBER, "error"], - [IntMode.MIXED, BigInt("0x7fffffffffffffff")], - [IntMode.BIGINT, BigInt("0x7fffffffffffffff")], - ]), - }, - INT64_MIN: { - input: BigInt(-1) * BigInt("0x8000000000000000"), - expected: new Map([ - // exclude IntMode.UNSAFE_NUMBER, behavior will not be exact - [IntMode.SAFE_NUMBER, "error"], - [IntMode.MIXED, BigInt(-1) * BigInt("0x8000000000000000")], - [IntMode.BIGINT, BigInt(-1) * BigInt("0x8000000000000000")], - ]), - }, - }; -} - -// declared as a function to delay referencing the BigInt constructor -function BIGUINTSPECS(): Record { - return { - ZERO: { - input: BigInt(0), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, 0], - [IntMode.SAFE_NUMBER, 0], - [IntMode.MIXED, 0], - [IntMode.BIGINT, BigInt(0)], - ]), - }, - ONE: { - input: BigInt(1), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, 1], - [IntMode.SAFE_NUMBER, 1], - [IntMode.MIXED, 1], - [IntMode.BIGINT, BigInt(1)], - ]), - }, - X_FF: { - input: BigInt(0xff), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, 0xff], - [IntMode.SAFE_NUMBER, 0xff], - [IntMode.MIXED, 0xff], - [IntMode.BIGINT, BigInt(0xff)], - ]), - }, - UINT32_MAX: { - input: BigInt(0xffffffff), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, 0xffffffff], - [IntMode.SAFE_NUMBER, 0xffffffff], - [IntMode.MIXED, 0xffffffff], - [IntMode.BIGINT, BigInt(0xffffffff)], - ]), - }, - MAX_SAFE_INTEGER: { - input: BigInt(Number.MAX_SAFE_INTEGER), - expected: new Map([ - [IntMode.UNSAFE_NUMBER, Number.MAX_SAFE_INTEGER], - [IntMode.SAFE_NUMBER, Number.MAX_SAFE_INTEGER], - [IntMode.MIXED, Number.MAX_SAFE_INTEGER], - [IntMode.BIGINT, BigInt(Number.MAX_SAFE_INTEGER)], - ]), - }, - MAX_SAFE_INTEGER_PLUS_ONE: { - input: BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1), - expected: new Map([ - // exclude IntMode.UNSAFE_NUMBER, behavior will not be exact - [IntMode.SAFE_NUMBER, "error"], - [IntMode.MIXED, BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1)], - [IntMode.BIGINT, BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1)], - ]), - }, - UINT64_MAX: { - input: BigInt("0xffffffffffffffff"), - expected: new Map([ - // exclude IntMode.UNSAFE_NUMBER, behavior will not be exact - [IntMode.SAFE_NUMBER, "error"], - [IntMode.MIXED, BigInt("0xffffffffffffffff")], - [IntMode.BIGINT, BigInt("0xffffffffffffffff")], - ]), - }, - }; -} - -function abs(value: bigint): bigint { - if (value < 0) { - return BigInt(-1) * value; - } - return value; -} - -const extensionCodec = new ExtensionCodec(); -extensionCodec.register({ - type: 0, - encode: (input: unknown) => { - if (typeof input === "bigint") { - if (input <= Number.MAX_SAFE_INTEGER && input >= Number.MIN_SAFE_INTEGER) { - return encode(parseInt(input.toString(), 10)); - } else { - return encode(input.toString()); - } - } else { - return null; - } - }, - decode: (data: Uint8Array) => { - const val = decode(data); - if (!(typeof val === "string" || typeof val === "number")) { - throw new DecodeError(`unexpected BigInt source: ${val} (${typeof val})`); - } - return BigInt(val); - }, -}); -context("extension", () => { - it("encodes and decodes 0n", () => { - const value = BigInt(0); - const encoded = encode(value, { extensionCodec }); - assert.deepStrictEqual(decode(encoded, { extensionCodec }), value); - }); - - it("encodes and decodes MAX_SAFE_INTEGER+1", () => { - const value = BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1); - const encoded = encode(value, { extensionCodec }); - assert.deepStrictEqual(decode(encoded, { extensionCodec }), value); - }); - - it("encodes and decodes MIN_SAFE_INTEGER-1", () => { - const value = BigInt(Number.MIN_SAFE_INTEGER) - BigInt(1); - const encoded = encode(value, { extensionCodec }); - assert.deepStrictEqual(decode(encoded, { extensionCodec }), value); - }); -}); - -context("native", () => { - context("int 64", () => { - const specs = BIGINTSPECS(); - - for (const name of Object.keys(specs)) { - const testCase = specs[name]!; - - it(`sets and gets ${testCase.input} (${testCase.input < 0 ? "-" : ""}0x${abs(testCase.input).toString( - 16, - )})`, () => { - const b = new Uint8Array(8); - const view = new DataView(b.buffer); - view.setBigInt64(0, testCase.input); - for (const [mode, expected] of testCase.expected) { - if (expected === "error") { - assert.throws( - () => getInt64(view, 0, mode), - new RegExp( - `Mode is IntMode\\.SAFE_NUMBER and value is not a safe integer: ${testCase.input < 0 ? "-" : ""}0x${abs( - testCase.input, - ).toString(16)}$`, - ), - ); - continue; - } - assert.deepStrictEqual(getInt64(view, 0, mode), expected); - } - }); - } - }); - - context("uint 64", () => { - const specs = BIGUINTSPECS(); - - for (const name of Object.keys(specs)) { - const testCase = specs[name]!; - - it(`sets and gets ${testCase.input} (0x${testCase.input.toString(16)})`, () => { - const b = new Uint8Array(8); - const view = new DataView(b.buffer); - view.setBigUint64(0, testCase.input); - for (const [mode, expected] of testCase.expected) { - if (expected === "error") { - assert.throws( - () => getUint64(view, 0, mode), - new RegExp( - `Mode is IntMode\\.SAFE_NUMBER and value is not a safe integer: 0x${testCase.input.toString(16)}$`, - ), - ); - continue; - } - assert.deepStrictEqual(getUint64(view, 0, mode), expected); - } - }); - } - }); -}); diff --git a/test/codec-bigint.test.ts b/test/codec-bigint.test.ts index 408e6fee..52b8f410 100644 --- a/test/codec-bigint.test.ts +++ b/test/codec-bigint.test.ts @@ -31,8 +31,8 @@ extensionCodec.register({ }); interface TestCase { - input: bigint, - expected: Map, + input: bigint; + expected: Map; } // declared as a function to delay referencing the BigInt constructor @@ -45,7 +45,7 @@ function BIGINTSPECS(): Record { [IntMode.SAFE_NUMBER, 0], [IntMode.MIXED, 0], [IntMode.BIGINT, BigInt(0)], - ]) + ]), }, ONE: { input: BigInt(1), @@ -54,7 +54,7 @@ function BIGINTSPECS(): Record { [IntMode.SAFE_NUMBER, 1], [IntMode.MIXED, 1], [IntMode.BIGINT, BigInt(1)], - ]) + ]), }, MINUS_ONE: { input: BigInt(-1), @@ -63,7 +63,7 @@ function BIGINTSPECS(): Record { [IntMode.SAFE_NUMBER, -1], [IntMode.MIXED, -1], [IntMode.BIGINT, BigInt(-1)], - ]) + ]), }, X_FF: { input: BigInt(0xff), @@ -72,7 +72,7 @@ function BIGINTSPECS(): Record { [IntMode.SAFE_NUMBER, 0xff], [IntMode.MIXED, 0xff], [IntMode.BIGINT, BigInt(0xff)], - ]) + ]), }, MINUS_X_FF: { input: BigInt(-0xff), @@ -81,7 +81,7 @@ function BIGINTSPECS(): Record { [IntMode.SAFE_NUMBER, -0xff], [IntMode.MIXED, -0xff], [IntMode.BIGINT, BigInt(-0xff)], - ]) + ]), }, INT32_MAX: { input: BigInt(0x7fffffff), @@ -90,7 +90,7 @@ function BIGINTSPECS(): Record { [IntMode.SAFE_NUMBER, 0x7fffffff], [IntMode.MIXED, 0x7fffffff], [IntMode.BIGINT, BigInt(0x7fffffff)], - ]) + ]), }, INT32_MIN: { input: BigInt(-0x7fffffff - 1), @@ -99,7 +99,7 @@ function BIGINTSPECS(): Record { [IntMode.SAFE_NUMBER, -0x7fffffff - 1], [IntMode.MIXED, -0x7fffffff - 1], [IntMode.BIGINT, BigInt(-0x7fffffff - 1)], - ]) + ]), }, MAX_SAFE_INTEGER: { input: BigInt(Number.MAX_SAFE_INTEGER), @@ -108,7 +108,7 @@ function BIGINTSPECS(): Record { [IntMode.SAFE_NUMBER, Number.MAX_SAFE_INTEGER], [IntMode.MIXED, Number.MAX_SAFE_INTEGER], [IntMode.BIGINT, BigInt(Number.MAX_SAFE_INTEGER)], - ]) + ]), }, MAX_SAFE_INTEGER_PLUS_ONE: { input: BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1), @@ -117,7 +117,7 @@ function BIGINTSPECS(): Record { [IntMode.SAFE_NUMBER, "error"], [IntMode.MIXED, BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1)], [IntMode.BIGINT, BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1)], - ]) + ]), }, MIN_SAFE_INTEGER: { input: BigInt(Number.MIN_SAFE_INTEGER), @@ -126,7 +126,7 @@ function BIGINTSPECS(): Record { [IntMode.SAFE_NUMBER, Number.MIN_SAFE_INTEGER], [IntMode.MIXED, Number.MIN_SAFE_INTEGER], [IntMode.BIGINT, BigInt(Number.MIN_SAFE_INTEGER)], - ]) + ]), }, MIN_SAFE_INTEGER_MINUS_ONE: { input: BigInt(Number.MIN_SAFE_INTEGER) - BigInt(1), @@ -144,7 +144,7 @@ function BIGINTSPECS(): Record { [IntMode.SAFE_NUMBER, "error"], [IntMode.MIXED, BigInt("0x7fffffffffffffff")], [IntMode.BIGINT, BigInt("0x7fffffffffffffff")], - ]) + ]), }, INT64_MIN: { input: BigInt(-1) * BigInt("0x8000000000000000"), @@ -155,7 +155,7 @@ function BIGINTSPECS(): Record { [IntMode.BIGINT, BigInt(-1) * BigInt("0x8000000000000000")], ]), }, - } + }; } // declared as a function to delay referencing the BigInt constructor @@ -168,7 +168,7 @@ function BIGUINTSPECS(): Record { [IntMode.SAFE_NUMBER, 0], [IntMode.MIXED, 0], [IntMode.BIGINT, BigInt(0)], - ]) + ]), }, ONE: { input: BigInt(1), @@ -177,7 +177,7 @@ function BIGUINTSPECS(): Record { [IntMode.SAFE_NUMBER, 1], [IntMode.MIXED, 1], [IntMode.BIGINT, BigInt(1)], - ]) + ]), }, X_FF: { input: BigInt(0xff), @@ -186,7 +186,7 @@ function BIGUINTSPECS(): Record { [IntMode.SAFE_NUMBER, 0xff], [IntMode.MIXED, 0xff], [IntMode.BIGINT, BigInt(0xff)], - ]) + ]), }, UINT32_MAX: { input: BigInt(0xffffffff), @@ -195,7 +195,7 @@ function BIGUINTSPECS(): Record { [IntMode.SAFE_NUMBER, 0xffffffff], [IntMode.MIXED, 0xffffffff], [IntMode.BIGINT, BigInt(0xffffffff)], - ]) + ]), }, MAX_SAFE_INTEGER: { input: BigInt(Number.MAX_SAFE_INTEGER), @@ -204,7 +204,7 @@ function BIGUINTSPECS(): Record { [IntMode.SAFE_NUMBER, Number.MAX_SAFE_INTEGER], [IntMode.MIXED, Number.MAX_SAFE_INTEGER], [IntMode.BIGINT, BigInt(Number.MAX_SAFE_INTEGER)], - ]) + ]), }, MAX_SAFE_INTEGER_PLUS_ONE: { input: BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1), @@ -213,7 +213,7 @@ function BIGUINTSPECS(): Record { [IntMode.SAFE_NUMBER, "error"], [IntMode.MIXED, BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1)], [IntMode.BIGINT, BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1)], - ]) + ]), }, UINT64_MAX: { input: BigInt("0xffffffffffffffff"), @@ -222,9 +222,9 @@ function BIGUINTSPECS(): Record { [IntMode.SAFE_NUMBER, "error"], [IntMode.MIXED, BigInt("0xffffffffffffffff")], [IntMode.BIGINT, BigInt("0xffffffffffffffff")], - ]) + ]), }, - } + }; } function abs(value: bigint): bigint { @@ -241,13 +241,13 @@ describe("codec BigInt", () => { const encoded = encode(value, { extensionCodec }); assert.deepStrictEqual(decode(encoded, { extensionCodec }), value); }); - + it("encodes and decodes MAX_SAFE_INTEGER+1", () => { const value = BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1); const encoded = encode(value, { extensionCodec }); assert.deepStrictEqual(decode(encoded, { extensionCodec }), value); }); - + it("encodes and decodes MIN_SAFE_INTEGER-1", () => { const value = BigInt(Number.MIN_SAFE_INTEGER) - BigInt(1); const encoded = encode(value, { extensionCodec }); @@ -272,20 +272,30 @@ describe("codec BigInt", () => { const encoded = encode(value, { extensionCodec }); assert.deepStrictEqual(decode(encoded, { extensionCodec }), value); }); + context("native", () => { context("int 64", () => { const specs = BIGINTSPECS(); for (const name of Object.keys(specs)) { const testCase = specs[name]!; - - it(`sets and gets ${testCase.input} (${testCase.input < 0 ? "-" : ""}0x${abs(testCase.input).toString(16)})`, () => { + + it(`sets and gets ${testCase.input} (${testCase.input < 0 ? "-" : ""}0x${abs(testCase.input).toString( + 16, + )})`, () => { const b = new Uint8Array(8); const view = new DataView(b.buffer); view.setBigInt64(0, testCase.input); for (const [mode, expected] of testCase.expected) { if (expected === "error") { - assert.throws(() => getInt64(view, 0, mode), new RegExp(`Mode is IntMode\\.SAFE_NUMBER and value is not a safe integer: ${testCase.input < 0 ? "-" : ""}0x${abs(testCase.input).toString(16)}$`)); + assert.throws( + () => getInt64(view, 0, mode), + new RegExp( + `Mode is IntMode\\.SAFE_NUMBER and value is not a safe integer: ${ + testCase.input < 0 ? "-" : "" + }0x${abs(testCase.input).toString(16)}$`, + ), + ); continue; } assert.deepStrictEqual(getInt64(view, 0, mode), expected); @@ -299,14 +309,19 @@ describe("codec BigInt", () => { for (const name of Object.keys(specs)) { const testCase = specs[name]!; - + it(`sets and gets ${testCase.input} (0x${testCase.input.toString(16)})`, () => { const b = new Uint8Array(8); const view = new DataView(b.buffer); view.setBigUint64(0, testCase.input); for (const [mode, expected] of testCase.expected) { if (expected === "error") { - assert.throws(() => getUint64(view, 0, mode), new RegExp(`Mode is IntMode\\.SAFE_NUMBER and value is not a safe integer: 0x${testCase.input.toString(16)}$`)); + assert.throws( + () => getUint64(view, 0, mode), + new RegExp( + `Mode is IntMode\\.SAFE_NUMBER and value is not a safe integer: 0x${testCase.input.toString(16)}$`, + ), + ); continue; } assert.deepStrictEqual(getUint64(view, 0, mode), expected); @@ -315,4 +330,34 @@ describe("codec BigInt", () => { } }); }); + + context("IntMode.AS_ENCODED vs IntMode.Mixed", () => { + it("decodes 64-bit integers properly", () => { + let input = Uint8Array.from([0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3]); + assert.deepStrictEqual(decode(input, { intMode: IntMode.AS_ENCODED }), BigInt(3)); + assert.deepStrictEqual(decode(input, { intMode: IntMode.MIXED }), 3); + + input = Uint8Array.from([0xd3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6]); + assert.deepStrictEqual(decode(input, { intMode: IntMode.AS_ENCODED }), BigInt(-10)); + assert.deepStrictEqual(decode(input, { intMode: IntMode.MIXED }), -10); + + input = Uint8Array.from([0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); + assert.deepStrictEqual(decode(input, { intMode: IntMode.AS_ENCODED }), BigInt("0xffffffffffffffff")); + assert.deepStrictEqual(decode(input, { intMode: IntMode.MIXED }), BigInt("0xffffffffffffffff")); + }); + + it("decodes smaller integers properly", () => { + let input = Uint8Array.from([0x03]); + assert.deepStrictEqual(decode(input, { intMode: IntMode.AS_ENCODED }), 3); + assert.deepStrictEqual(decode(input, { intMode: IntMode.MIXED }), 3); + + input = Uint8Array.from([0xf6]); + assert.deepStrictEqual(decode(input, { intMode: IntMode.AS_ENCODED }), -10); + assert.deepStrictEqual(decode(input, { intMode: IntMode.MIXED }), -10); + + input = Uint8Array.from([0xce, 0xff, 0xff, 0xff, 0xff]); + assert.deepStrictEqual(decode(input, { intMode: IntMode.AS_ENCODED }), 0xffffffff); + assert.deepStrictEqual(decode(input, { intMode: IntMode.MIXED }), 0xffffffff); + }); + }); }); diff --git a/test/encode.test.ts b/test/encode.test.ts index cfa3efe7..6f88e4df 100644 --- a/test/encode.test.ts +++ b/test/encode.test.ts @@ -94,6 +94,38 @@ describe("encode", () => { assert.deepStrictEqual(decode(arrayBuffer), decode(buffer)); }); + context("forceBigIntToInt64", () => { + if (typeof BigInt !== "undefined") { + it("encodes bigints as integers without forceBigIntToInt64", () => { + let input = BigInt(3); + let expected = Uint8Array.from([0x03]); + assert.deepStrictEqual(encode(input), expected); + + input = BigInt(-10); + expected = Uint8Array.from([0xf6]); + assert.deepStrictEqual(encode(input), expected); + + input = BigInt("0xffffffffffffffff"); + expected = Uint8Array.from([0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); + assert.deepStrictEqual(encode(input), expected); + }); + + it("encodes bigints as int64 when forceBigIntToInt64=true", () => { + let input = BigInt(3); + let expected = Uint8Array.from([0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03]); + assert.deepStrictEqual(encode(input, { forceBigIntToInt64: true }), expected); + + input = BigInt(-10); + expected = Uint8Array.from([0xd3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6]); + assert.deepStrictEqual(encode(input, { forceBigIntToInt64: true }), expected); + + input = BigInt("0xffffffffffffffff"); + expected = Uint8Array.from([0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); + assert.deepStrictEqual(encode(input), expected); + }); + } + }); + context("Bigint that exceeds 64 bits", () => { if (typeof BigInt !== "undefined") { const MAX_UINT64_PLUS_ONE = BigInt("0x10000000000000000");