ox
Version:
Ethereum Standard Library
208 lines (193 loc) • 5.23 kB
text/typescript
import { assertType, expect, test } from 'vp/test'
import { parseAbiParameter } from './parseAbiParameter.js'
test('parseAbiParameter', () => {
// @ts-expect-error invalid signature type
expect(() => parseAbiParameter('')).toThrowErrorMatchingInlineSnapshot(
`[HumanReadableAbi.InvalidParameterError: Invalid ABI parameter.]`,
)
// @ts-expect-error invalid signature type
expect(() => parseAbiParameter([])).toThrowErrorMatchingInlineSnapshot(
`
[AbiParameter.InvalidAbiParameterError: Failed to parse ABI parameter.
Details: parseAbiParameter([])
See: https://oxlib.sh/api/AbiParameter/from]
`,
)
expect(() =>
parseAbiParameter(['struct Foo { string name; }']),
).toThrowErrorMatchingInlineSnapshot(
`
[AbiParameter.InvalidAbiParameterError: Failed to parse ABI parameter.
Details: parseAbiParameter([
"struct Foo { string name; }"
])
See: https://oxlib.sh/api/AbiParameter/from]
`,
)
expect(() =>
parseAbiParameter(['struct Foo { string memory bar; }', 'Foo indexed foo']),
).toThrowErrorMatchingInlineSnapshot(
`
[HumanReadableAbi.InvalidModifierError: Invalid ABI parameter.
Modifier "memory" not allowed in "struct" type.
Details: string memory bar]
`,
)
expect([parseAbiParameter('address from')]).toMatchInlineSnapshot(`
[
{
"name": "from",
"type": "address",
},
]
`)
})
test.each([
{ signature: 'string', expected: { type: 'string' } },
{ signature: 'string foo', expected: { name: 'foo', type: 'string' } },
{
signature: 'string indexed foo',
expected: { name: 'foo', type: 'string', indexed: true },
},
{
signature: 'string calldata foo',
expected: { name: 'foo', type: 'string' },
},
{
signature: '(string)',
expected: { type: 'tuple', components: [{ type: 'string' }] },
},
{
signature: '(string foo)',
expected: { type: 'tuple', components: [{ name: 'foo', type: 'string' }] },
},
{
signature: '(string bar) foo',
expected: {
type: 'tuple',
name: 'foo',
components: [{ name: 'bar', type: 'string' }],
},
},
{
signature: '(string bar, string baz) foo',
expected: {
type: 'tuple',
name: 'foo',
components: [
{ name: 'bar', type: 'string' },
{ name: 'baz', type: 'string' },
],
},
},
{ signature: 'string[]', expected: { type: 'string[]' } },
])('parseAbiParameter($signature)', ({ signature, expected }) => {
expect(parseAbiParameter(signature)).toEqual(expected)
})
test.each([
{
signatures: ['struct Foo { string bar; }', 'Foo'],
expected: { type: 'tuple', components: [{ name: 'bar', type: 'string' }] },
},
{
signatures: ['struct Foo { string bar; }', 'Foo foo'],
expected: {
type: 'tuple',
name: 'foo',
components: [{ name: 'bar', type: 'string' }],
},
},
{
signatures: ['struct Foo { string bar; }', 'Foo indexed foo'],
expected: {
type: 'tuple',
name: 'foo',
indexed: true,
components: [{ name: 'bar', type: 'string' }],
},
},
])('parseAbiParameter($signatures)', ({ signatures, expected }) => {
expect(parseAbiParameter(signatures)).toEqual(expected)
})
test('nested tuple', () => {
const result = parseAbiParameter('((((string baz) bar)[1] foo) boo)')
expect(result).toMatchInlineSnapshot(`
{
"components": [
{
"components": [
{
"components": [
{
"components": [
{
"name": "baz",
"type": "string",
},
],
"name": "bar",
"type": "tuple",
},
],
"name": "foo",
"type": "tuple[1]",
},
],
"name": "boo",
"type": "tuple",
},
],
"type": "tuple",
}
`)
assertType<{
type: 'tuple'
components: readonly [
{
type: 'tuple'
components: readonly [
{
type: 'tuple[1]'
components: readonly [
{
type: 'tuple'
components: readonly [
{
type: 'string'
name: 'baz'
},
]
name: 'bar'
},
]
name: 'foo'
},
]
name: 'boo'
},
]
}>(result)
})
test('struct name collision', () => {
const result1 = parseAbiParameter(['struct Foo { string bar; }', 'Foo'])
expect(result1).toEqual({
type: 'tuple',
components: [{ name: 'bar', type: 'string' }],
})
const result2 = parseAbiParameter(['struct Foo { address bar; }', 'Foo'])
expect(result2).toEqual({
type: 'tuple',
components: [{ name: 'bar', type: 'address' }],
})
const result3 = parseAbiParameter([
'struct Foo { uint256 amount; address token; }',
'Foo',
])
expect(result3).toEqual({
type: 'tuple',
components: [
{ name: 'amount', type: 'uint256' },
{ name: 'token', type: 'address' },
],
})
})