@hyperlane-xyz/core
Version:
Core solidity contracts for Hyperlane
315 lines (290 loc) • 7.45 kB
text/typescript
import { BigNumber } from '@ethersproject/bignumber'
/* Imports: Internal */
import { expect } from '../setup'
import {
toRpcHexString,
remove0x,
add0x,
fromHexString,
toHexString,
padHexString,
encodeHex,
hexStringEquals,
bytes32ify,
} from '../../src'
describe('remove0x', () => {
it('should return undefined', () => {
expect(remove0x(undefined)).to.deep.equal(undefined)
})
it('should return without a 0x', () => {
const cases = [
{ input: '0x', output: '' },
{
input: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
output: '1f9840a85d5af5bf1d1762f925bdaddc4201f984',
},
{ input: 'a', output: 'a' },
]
for (const test of cases) {
expect(remove0x(test.input)).to.deep.equal(test.output)
}
})
})
describe('add0x', () => {
it('should return undefined', () => {
expect(add0x(undefined)).to.deep.equal(undefined)
})
it('should return with a 0x', () => {
const cases = [
{ input: '0x', output: '0x' },
{
input: '1f9840a85d5af5bf1d1762f925bdaddc4201f984',
output: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
},
{ input: '', output: '0x' },
]
for (const test of cases) {
expect(add0x(test.input)).to.deep.equal(test.output)
}
})
})
describe('toHexString', () => {
it('should throw an error when input is null', () => {
expect(() => {
toHexString(null)
}).to.throw(
'The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received null'
)
})
it('should return with a hex string', () => {
const cases = [
{ input: 0, output: '0x00' },
{ input: 48, output: '0x30' },
{
input: '0',
output: '0x30',
},
{ input: '', output: '0x' },
]
for (const test of cases) {
expect(toHexString(test.input)).to.deep.equal(test.output)
}
})
})
describe('fromHexString', () => {
it('should return a buffer from a hex string', () => {
const cases = [
{ input: '0x', output: Buffer.from('', 'hex') },
{
input: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
output: Buffer.from('1f9840a85d5af5bf1d1762f925bdaddc4201f984', 'hex'),
},
{ input: '', output: Buffer.from('', 'hex') },
{
input: Buffer.from('1f9840a85d5af5bf1d1762f925bdaddc4201f984'),
output: Buffer.from('1f9840a85d5af5bf1d1762f925bdaddc4201f984'),
},
]
for (const test of cases) {
expect(fromHexString(test.input)).to.deep.equal(test.output)
}
})
})
describe('padHexString', () => {
it('should return return input string if length is 2 + length * 2', () => {
expect(padHexString('abcd', 1)).to.deep.equal('abcd')
expect(padHexString('abcdefgh', 3).length).to.deep.equal(8)
})
it('should return a string padded with 0x and zeros', () => {
expect(padHexString('0xabcd', 3)).to.deep.equal('0x00abcd')
})
})
describe('toRpcHexString', () => {
it('should parse 0', () => {
expect(toRpcHexString(0)).to.deep.equal('0x0')
expect(toRpcHexString(BigNumber.from(0))).to.deep.equal('0x0')
})
it('should parse non 0', () => {
const cases = [
{ input: 2, output: '0x2' },
{ input: BigNumber.from(2), output: '0x2' },
{ input: 100, output: '0x64' },
{ input: BigNumber.from(100), output: '0x64' },
{ input: 300, output: '0x12c' },
{ input: BigNumber.from(300), output: '0x12c' },
]
for (const test of cases) {
expect(toRpcHexString(test.input)).to.deep.equal(test.output)
}
})
})
describe('encodeHex', () => {
it('should throw an error when val is invalid', () => {
expect(() => {
encodeHex(null, 0)
}).to.throw('invalid BigNumber value')
expect(() => {
encodeHex(10.5, 0)
}).to.throw('fault="underflow", operation="BigNumber.from", value=10.5')
expect(() => {
encodeHex('10.5', 0)
}).to.throw('invalid BigNumber string')
})
it('should return a hex string of val with length len', () => {
const cases = [
{
input: {
val: 0,
len: 0,
},
output: '00',
},
{
input: {
val: 0,
len: 4,
},
output: '0000',
},
{
input: {
val: 1,
len: 0,
},
output: '01',
},
{
input: {
val: 1,
len: 10,
},
output: '0000000001',
},
{
input: {
val: 100,
len: 4,
},
output: '0064',
},
{
input: {
val: '100',
len: 0,
},
output: '64',
},
]
for (const test of cases) {
expect(encodeHex(test.input.val, test.input.len)).to.deep.equal(
test.output
)
}
})
})
describe('hexStringEquals', () => {
it('should throw an error when input is not a hex string', () => {
expect(() => {
hexStringEquals('', '')
}).to.throw('input is not a hex string: ')
expect(() => {
hexStringEquals('0xx', '0x1')
}).to.throw('input is not a hex string: 0xx')
expect(() => {
hexStringEquals('0x1', '2')
}).to.throw('input is not a hex string: 2')
expect(() => {
hexStringEquals('-0x1', '0x1')
}).to.throw('input is not a hex string: -0x1')
})
it('should return the hex strings equality', () => {
const cases = [
{
input: {
stringA: '0x',
stringB: '0x',
},
output: true,
},
{
input: {
stringA: '0x1',
stringB: '0x1',
},
output: true,
},
{
input: {
stringA: '0x064',
stringB: '0x064',
},
output: true,
},
{
input: {
stringA: '0x',
stringB: '0x0',
},
output: false,
},
{
input: {
stringA: '0x0',
stringB: '0x1',
},
output: false,
},
{
input: {
stringA: '0x64',
stringB: '0x064',
},
output: false,
},
]
for (const test of cases) {
expect(
hexStringEquals(test.input.stringA, test.input.stringB)
).to.deep.equal(test.output)
}
})
})
describe('bytes32ify', () => {
it('should throw an error when input is invalid', () => {
expect(() => {
bytes32ify(-1)
}).to.throw('invalid hex string')
})
it('should return a zero padded, 32 bytes hex string', () => {
const cases = [
{
input: 0,
output:
'0x0000000000000000000000000000000000000000000000000000000000000000',
},
{
input: BigNumber.from(0),
output:
'0x0000000000000000000000000000000000000000000000000000000000000000',
},
{
input: 2,
output:
'0x0000000000000000000000000000000000000000000000000000000000000002',
},
{
input: BigNumber.from(2),
output:
'0x0000000000000000000000000000000000000000000000000000000000000002',
},
{
input: 100,
output:
'0x0000000000000000000000000000000000000000000000000000000000000064',
},
]
for (const test of cases) {
expect(bytes32ify(test.input)).to.deep.equal(test.output)
}
})
})