diff --git a/src/utils/bytes.ts b/src/utils/bytes.ts index 06b4bd5e..5ca11896 100644 --- a/src/utils/bytes.ts +++ b/src/utils/bytes.ts @@ -14,7 +14,7 @@ export type Bytes = ArrayLike; * @example * '0x123' */ -// export type BytesLike = Bytes | string | number; + export type BytesLike = Bytes | string; export type BytesLikeWithNumber = BytesLike | number; diff --git a/src/utils/tests/bytes/hex-concat.test.ts b/src/utils/tests/bytes/hex-concat.test.ts new file mode 100644 index 00000000..bfbb1bd3 --- /dev/null +++ b/src/utils/tests/bytes/hex-concat.test.ts @@ -0,0 +1,28 @@ +import { utils as ethers } from 'ethers'; +import { hexConcat } from '../../bytes'; + +describe('utils.hexConcat', () => { + it('should match ethers.js - hex values', () => { + const values = ['0x2048', '0x6917', '0x85616379']; + expect(hexConcat(values)).toBe(ethers.hexConcat(values)); + }); + it('should match ethers.js - UInt8Array values', () => { + const values = [ + [5, 10, 247, 22], + [50, 255, 3], + [59, 36, 18, 46, 198, 234], + ]; + expect(hexConcat(values)).toBe(ethers.hexConcat(values)); + }); + it('should match ethers.js - hex & UInt8Array values', () => { + const values = [ + '0x2048', + [5, 10, 247, 22], + '0x6917', + [50, 255, 3], + '0x85616379', + [59, 36, 18, 46, 198, 234], + ]; + expect(hexConcat(values)).toBe(ethers.hexConcat(values)); + }); +}); diff --git a/src/utils/tests/bytes/hex-data-length.test.ts b/src/utils/tests/bytes/hex-data-length.test.ts new file mode 100644 index 00000000..9bec5d41 --- /dev/null +++ b/src/utils/tests/bytes/hex-data-length.test.ts @@ -0,0 +1,27 @@ +import { utils as ethers } from 'ethers'; +import { hexDataLength } from '../../bytes'; + +describe('utils.hexDataLength', () => { + it('should match ethers.js - hex values', () => { + const values = ['0x9347', '0x185754', '0x00005823']; + values.forEach((value) => { + expect(hexDataLength(value)).toBe(ethers.hexDataLength(value)); + }); + }); + it('should match ethers.js - UInt8Array values', () => { + const values = [ + [9, 58, 29, 24], + [185, 203], + [239, 30, 49, 41, 5, 10, 42], + ]; + values.forEach((value) => { + expect(hexDataLength(value)).toBe(ethers.hexDataLength(value)); + }); + }); + it('should return null - not hex value or not divisible by 2', () => { + const values = ['0x383', 'non-hex string']; + values.forEach((value) => { + expect(hexDataLength(value)).toBeNull(); + }); + }); +}); diff --git a/src/utils/tests/bytes/hex-data-slice.test.ts b/src/utils/tests/bytes/hex-data-slice.test.ts index 91fdba95..4fe7c0ab 100644 --- a/src/utils/tests/bytes/hex-data-slice.test.ts +++ b/src/utils/tests/bytes/hex-data-slice.test.ts @@ -1,12 +1,12 @@ -import * as ethers from 'ethers'; -import { hexDataSlice } from '../../../'; +import { utils as ethers } from 'ethers'; +import { hexDataSlice } from '../../bytes'; -describe('hexDataSlice', () => { +describe('utils.hexDataSlice', () => { it('numbers - matches ethers strings', () => { const decimalValues = ['0x123456']; decimalValues.forEach((decimalValue) => { expect(hexDataSlice(decimalValue, 0, 2)).toStrictEqual( - ethers.utils.hexDataSlice(decimalValue, 0, 2), + ethers.hexDataSlice(decimalValue, 0, 2), ); }); }); @@ -14,13 +14,13 @@ describe('hexDataSlice', () => { const decimalValues = [0x1234567891011]; decimalValues.forEach((decimalValue) => { expect(hexDataSlice(decimalValue, 3)).toStrictEqual( - ethers.utils.hexDataSlice(decimalValue as any, 3), + ethers.hexDataSlice(decimalValue as any, 3), ); expect(hexDataSlice(decimalValue, 2, 4)).toStrictEqual( - ethers.utils.hexDataSlice(decimalValue as any, 2, 4), + ethers.hexDataSlice(decimalValue as any, 2, 4), ); expect(hexDataSlice(decimalValue, 100)).toStrictEqual( - ethers.utils.hexDataSlice(decimalValue as any, 100), + ethers.hexDataSlice(decimalValue as any, 100), ); }); }); @@ -28,8 +28,14 @@ describe('hexDataSlice', () => { const decimalValues = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]; decimalValues.forEach((decimalValue) => { expect(hexDataSlice(decimalValue, 1, 2)).toStrictEqual( - ethers.utils.hexDataSlice(decimalValue as any, 1, 2), + ethers.hexDataSlice(decimalValue as any, 1, 2), ); }); }); + it('should throw error - invalid hexData', () => { + const values = ['non-hex string', '0x938']; + values.forEach((value) => { + expect(() => hexDataSlice(value, 1, 3)).toThrow('invalid hexData'); + }); + }); }); diff --git a/src/utils/tests/bytes/hex-strip-zeros.test.ts b/src/utils/tests/bytes/hex-strip-zeros.test.ts new file mode 100644 index 00000000..e04097a0 --- /dev/null +++ b/src/utils/tests/bytes/hex-strip-zeros.test.ts @@ -0,0 +1,27 @@ +import { utils as ethers } from 'ethers'; +import { hexStripZeros } from '../../bytes'; + +describe('utils.hexStripZeros', () => { + it('should match ethers.js - hex values', () => { + const values = ['0x00009347', '0x00185754', '0x00000000005823']; + values.forEach((value) => { + expect(hexStripZeros(value)).toBe(ethers.hexStripZeros(value)); + }); + }); + it('should match ethers.js - UInt8Array values', () => { + const values = [ + [0, 0, 0, 9, 58, 29, 24], + [0, 185, 203], + [0, 0, 0, 0, 239, 30, 49, 41, 5, 10, 42], + ]; + values.forEach((value) => { + expect(hexStripZeros(value)).toBe(ethers.hexStripZeros(value)); + }); + }); + it('should throw error - invalid hex string', () => { + const values = ['non-hex string']; + values.forEach((value) => { + expect(() => hexStripZeros(value)).toThrow('invalid hex string'); + }); + }); +}); diff --git a/src/utils/tests/bytes/hex-value.test.ts b/src/utils/tests/bytes/hex-value.test.ts new file mode 100644 index 00000000..67c7b55d --- /dev/null +++ b/src/utils/tests/bytes/hex-value.test.ts @@ -0,0 +1,46 @@ +import { utils as ethers } from 'ethers'; +import { hexValue } from '../../bytes'; +import { tinyBig } from './../../../shared/tiny-big/tiny-big'; + +describe('utils.hexValue', () => { + it('should match ethers.js - hex string', () => { + const values = ['0x9347', '0x185754', '0x00005823']; + values.forEach((value) => { + expect(hexValue(value)).toBe(ethers.hexValue(value)); + }); + }); + it('should match ethers.js - UInt8Array', () => { + const values = [ + [4, 50, 2], + [231, 49, 40, 70, 19], + [10, 68, 20, 98], + ]; + values.forEach((value) => { + expect(hexValue(value)).toBe(ethers.hexValue(value)); + }); + }); + it('should match ethers.js - TinyBig (hexable)', () => { + const values = [tinyBig('29389'), tinyBig(2834), tinyBig(402)]; + values.forEach((value) => { + expect(hexValue(value)).toBe(ethers.hexValue(value)); + }); + }); + it('should match ethers.js - number', () => { + const values = [624, 457, 23451]; + values.forEach((value) => { + expect(hexValue(value)).toBe(ethers.hexValue(value)); + }); + }); + it('should match ethers.js - BigInt', () => { + const values = [BigInt(204), BigInt('23491'), BigInt(4183459235723491)]; + values.forEach((value) => { + expect(hexValue(value)).toBe(ethers.hexValue(value)); + }); + }); + it('should return 0x0 - only zero data given', () => { + const values = [BigInt(0), 0, '0x0000', [0, 0, 0]]; + values.forEach((value) => { + expect(hexValue(value)).toBe('0x0'); + }); + }); +}); diff --git a/src/utils/tests/bytes/hexlify.test.ts b/src/utils/tests/bytes/hexlify.test.ts index 17ecfd41..d34a20a6 100644 --- a/src/utils/tests/bytes/hexlify.test.ts +++ b/src/utils/tests/bytes/hexlify.test.ts @@ -1,14 +1,40 @@ -import * as ethers from 'ethers'; -import { hexlify } from '../../../'; +import { utils as ethers } from 'ethers'; +import { hexlify } from '../../bytes'; +import { BytesLike } from './../../bytes'; -describe('hexlify', () => { +describe('utils.hexlify', () => { it('numbers - matches ethers strings', () => { const decimalValues = [0, 4, 5, 16, BigInt(0), BigInt(16)]; decimalValues.forEach((decimalValue) => { - expect(hexlify(decimalValue)).toBe(ethers.utils.hexlify(decimalValue)); + expect(hexlify(decimalValue)).toBe(ethers.hexlify(decimalValue)); }); const opts = { allowMissingPrefix: true }; - expect(hexlify('22', opts)).toBe(ethers.utils.hexlify('22', opts)); + expect(hexlify('22', opts)).toBe(ethers.hexlify('22', opts)); + }); + it('should match ethers.js - hexPad options', () => { + const values = [ + ['0x3342e95', { hexPad: 'left' }], + ['0x41c942c42', { hexPad: 'right' }], + ]; + values.forEach((value) => { + expect(hexlify(value[0] as any, value[1] as any)).toBe( + ethers.hexlify(value[0] as any, value[1] as any), + ); + }); + }); + it('should throw error - hex data is odd-length', () => { + const values = ['0x931', '0x34414']; + values.forEach((value) => { + expect(() => hexlify(value)).toThrow('hex data is odd-length'); + }); + }); + it('should throw error - invalid hexlify value', () => { + const values = ['non-hex string', false]; + values.forEach((value) => { + expect(() => hexlify(value as BytesLike)).toThrow( + 'invalid hexlify value', + ); + }); }); }); diff --git a/src/utils/tests/bytes/is-bytes-like.test.ts b/src/utils/tests/bytes/is-bytes-like.test.ts new file mode 100644 index 00000000..ba6d5c70 --- /dev/null +++ b/src/utils/tests/bytes/is-bytes-like.test.ts @@ -0,0 +1,39 @@ +import { utils as ethers } from 'ethers'; +import { isBytesLike } from '../../bytes'; + +describe('utils.isBytesLike', () => { + it('should match ethers.js - hex string', () => { + const values = ['0x9347', '0x185754', '0x00005823']; + values.forEach((value) => { + expect(isBytesLike(value)).toBe(ethers.isBytesLike(value)); + }); + }); + it('should match ethers.js - UInt8Array', () => { + const values = [ + [9, 58, 29, 24], + [185, 203], + [239, 30, 49, 41, 5, 10, 42], + ]; + values.forEach((value) => { + expect(isBytesLike(value)).toBe(ethers.isBytesLike(value)); + }); + }); + it('should match ethers.js - number', () => { + const values = [152, 513, 2354]; + values.forEach((value) => { + expect(isBytesLike(value)).toBe(ethers.isBytesLike(value)); + }); + }); + it('should match ethers.js - non-hex string', () => { + const values = ['essential-eth', 'ethers.js', 'ethereum']; + values.forEach((value) => { + expect(isBytesLike(value)).toBe(ethers.isBytesLike(value)); + }); + }); + it('should match ethers.js - boolean', () => { + const values = [false, true]; + values.forEach((value) => { + expect(isBytesLike(value)).toBe(ethers.isBytesLike(value)); + }); + }); +}); diff --git a/src/utils/tests/bytes/is-hex-string.test.ts b/src/utils/tests/bytes/is-hex-string.test.ts new file mode 100644 index 00000000..3e9a7c43 --- /dev/null +++ b/src/utils/tests/bytes/is-hex-string.test.ts @@ -0,0 +1,51 @@ +import { utils as ethers } from 'ethers'; +import { isHexString } from '../../bytes'; + +describe('utils.isHexString', () => { + it('should match ethers.js - hex string', () => { + const values = ['0x9347', '0x185754', '0x00005823']; + values.forEach((value) => { + expect(isHexString(value)).toBe(ethers.isHexString(value)); + }); + }); + it('should match ethers.js - hex string of specific length', () => { + const values = [ + ['0x9347', 2], + ['0x185754', 5], + ['0x00005823', 4], + ]; + values.forEach((value) => { + expect(isHexString(value[0], value[1] as number)).toBe( + ethers.isHexString(value[0], value[1] as number), + ); + }); + }); + it('should match ethers.js - UInt8Array', () => { + const values = [ + [9, 58, 29, 24], + [185, 203], + [239, 30, 49, 41, 5, 10, 42], + ]; + values.forEach((value) => { + expect(isHexString(value)).toBe(ethers.isHexString(value)); + }); + }); + it('should match ethers.js - number', () => { + const values = [152, 513, 2354]; + values.forEach((value) => { + expect(isHexString(value)).toBe(ethers.isHexString(value)); + }); + }); + it('should match ethers.js - non-hex string', () => { + const values = ['essential-eth', 'ethers.js', 'ethereum']; + values.forEach((value) => { + expect(isHexString(value)).toBe(ethers.isHexString(value)); + }); + }); + it('should match ethers.js - boolean', () => { + const values = [false, true]; + values.forEach((value) => { + expect(isHexString(value)).toBe(ethers.isHexString(value)); + }); + }); +}); diff --git a/src/utils/tests/bytes/strip-zeros.test.ts b/src/utils/tests/bytes/strip-zeros.test.ts new file mode 100644 index 00000000..52360e43 --- /dev/null +++ b/src/utils/tests/bytes/strip-zeros.test.ts @@ -0,0 +1,27 @@ +import { utils as ethers } from 'ethers'; +import { stripZeros } from '../../bytes'; + +describe('utils.stripZeros', () => { + it('should match ethers.js - hex string', () => { + const values = ['0x00009347', '0x00185754', '0x00000000005823']; + values.forEach((value) => { + expect(stripZeros(value)).toStrictEqual(ethers.stripZeros(value)); + }); + }); + it('should match ethers.js - UInt8Array', () => { + const values = [ + [0, 0, 0, 9, 58, 29, 24], + [0, 185, 203], + [0, 0, 0, 0, 239, 30, 49, 41, 5, 10, 42], + ]; + values.forEach((value) => { + expect(stripZeros(value)).toStrictEqual(ethers.stripZeros(value)); + }); + }); + it('should match ethers.js - empty array', () => { + const values = [[], '0x']; + values.forEach((value) => { + expect(stripZeros(value)).toStrictEqual(ethers.stripZeros(value)); + }); + }); +}); diff --git a/src/utils/tests/bytes/zero-pad.test.ts b/src/utils/tests/bytes/zero-pad.test.ts new file mode 100644 index 00000000..8f88a66d --- /dev/null +++ b/src/utils/tests/bytes/zero-pad.test.ts @@ -0,0 +1,41 @@ +import { utils as ethers } from 'ethers'; +import { zeroPad } from '../../bytes'; +import { BytesLike } from './../../bytes'; + +describe('utils.zeroPad', () => { + it('should match ethers.js - hex string', () => { + const values = [ + ['0x9347', 10], + ['0x185754', 5], + ['0x00005823', 7], + ]; + values.forEach((value) => { + expect(zeroPad(value[0] as string, value[1] as number)).toStrictEqual( + ethers.zeroPad(value[0] as string, value[1] as number), + ); + }); + }); + it('should match ethers.js - UInt8Array', () => { + const values = [ + [[9, 58, 29, 24], 5], + [[185, 203], 4], + [[239, 30, 49, 41, 5, 10, 42], 10], + ]; + values.forEach((value) => { + expect(zeroPad(value[0] as BytesLike, value[1] as number)).toStrictEqual( + ethers.zeroPad(value[0] as BytesLike, value[1] as number), + ); + }); + }); + it('should throw error - value out of range', () => { + const values = [ + [[9, 58, 29, 24], 3], + ['0x185754', 1], + ]; + values.forEach((value) => { + expect(() => zeroPad(value[0] as BytesLike, value[1] as number)).toThrow( + 'value out of range', + ); + }); + }); +});