Skip to content

Commit

Permalink
🧪 Tests for tuples abi arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
coccoinomane committed Feb 17, 2024
1 parent 0c6a616 commit 6286615
Showing 1 changed file with 134 additions and 77 deletions.
211 changes: 134 additions & 77 deletions tests/web3core/helpers/test_abi_helper.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from typing import cast

import pytest
from hexbytes import HexBytes
from web3.exceptions import InvalidAddress
from web3.types import ABI
from web3.types import ABI, ABIFunctionParams

from web3cli.exceptions import Web3CliError
from web3core.exceptions import AbiOverflow
from web3core.exceptions import AbiOverflow, NotSupportedYet
from web3core.helpers.abi import (
decode_function_data,
get_event_full_signatures,
Expand Down Expand Up @@ -94,92 +96,92 @@ def test_get_event_full_signatures(erc20_abi: ABI) -> None:

def test_parse_abi_value_int() -> None:
# Test parsing of signed and unsigned values
assert parse_abi_value("uint256", "0") == 0
assert parse_abi_value("int256", "0") == 0
assert parse_abi_value("uint256", "123") == 123
assert parse_abi_value("int256", "123") == 123
assert parse_abi_value("uint256", "0000123") == 123
assert parse_abi_value("int256", "0000123") == 123
assert parse_abi_value("int256", "-123") == -123
assert parse_abi_value("int256", "-0123") == -123
assert parse_abi_value("uint256", "123456789") == 123456789
assert parse_abi_value("int256", "123456789") == 123456789
assert parse_abi_value("int256", "-123456789") == -123456789
assert parse_abi_value("0", "uint256") == 0
assert parse_abi_value("0", "int256") == 0
assert parse_abi_value("123", "uint256") == 123
assert parse_abi_value("123", "int256") == 123
assert parse_abi_value("0000123", "uint256") == 123
assert parse_abi_value("0000123", "int256") == 123
assert parse_abi_value("-123", "int256") == -123
assert parse_abi_value("-0123", "int256") == -123
assert parse_abi_value("123456789", "uint256") == 123456789
assert parse_abi_value("123456789", "int256") == 123456789
assert parse_abi_value("-123456789", "int256") == -123456789
assert (
parse_abi_value("uint256", "123456789012345678901234567890")
parse_abi_value("123456789012345678901234567890", "uint256")
== 123456789012345678901234567890
)
assert (
parse_abi_value("int256", "123456789012345678901234567890")
parse_abi_value("123456789012345678901234567890", "int256")
== 123456789012345678901234567890
)
# Test overflow of unsigned values
assert parse_abi_value("uint256", str(2**255)) == 2**255
assert pytest.raises(AbiOverflow, parse_abi_value, "uint256", str(2**256))
assert pytest.raises(AbiOverflow, parse_abi_value, "uint256", str(2**256))
assert parse_abi_value(str(2**255), "uint256") == 2**255
assert pytest.raises(AbiOverflow, parse_abi_value, str(2**256), "uint256")
assert pytest.raises(AbiOverflow, parse_abi_value, str(2**256), "uint256")
# Test overflow of signed values
assert parse_abi_value("int256", str(2**254)) == 2**254
assert pytest.raises(AbiOverflow, parse_abi_value, "int256", str(2**255))
assert parse_abi_value(str(2**254), "int256") == 2**254
assert pytest.raises(AbiOverflow, parse_abi_value, str(2**255), "int256")
# Can't parse negative values for unsigned values
assert pytest.raises(ValueError, parse_abi_value, "uint256", "-123")
assert pytest.raises(ValueError, parse_abi_value, "uint256", "-123456789")
assert pytest.raises(ValueError, parse_abi_value, "-123", "uint256")
assert pytest.raises(ValueError, parse_abi_value, "-123456789", "uint256")
# Test strings in exponential notation
assert parse_abi_value("uint256", "1e+18") == 10**18
assert parse_abi_value("uint256", "1e18") == 10**18
assert parse_abi_value("uint256", "1.1e18") == 11 * 10**17
assert parse_abi_value("uint256", "5e18") == 5 * 10**18
assert parse_abi_value("int256", "-5e18") == -5 * 10**18
assert parse_abi_value("1e+18", "uint256") == 10**18
assert parse_abi_value("1e18", "uint256") == 10**18
assert parse_abi_value("1.1e18", "uint256") == 11 * 10**17
assert parse_abi_value("5e18", "uint256") == 5 * 10**18
assert parse_abi_value("-5e18", "int256") == -5 * 10**18
with pytest.raises(ValueError):
assert parse_abi_value("uint256", "-5e18") == -5 * 10**18
assert parse_abi_value("-5e18", "uint256") == -5 * 10**18
with pytest.raises(AbiOverflow):
parse_abi_value("uint256", "1e200")
parse_abi_value("1e200", "uint256")
with pytest.raises(ValueError):
parse_abi_value("uint256", "1e+18", allow_exp_notation=False)
parse_abi_value("1e+18", "uint256", allow_exp_notation=False)
with pytest.raises(ValueError):
parse_abi_value("uint256", "1e18", allow_exp_notation=False)
parse_abi_value("1e18", "uint256", allow_exp_notation=False)
# Test that passing float numbers will error
assert pytest.raises(ValueError, parse_abi_value, "uint256", "1.1")
assert pytest.raises(ValueError, parse_abi_value, "uint256", "1.12345e1")
assert pytest.raises(ValueError, parse_abi_value, "uint256", "1.12345e2")
assert pytest.raises(ValueError, parse_abi_value, "uint256", "1.12345e3")
assert pytest.raises(ValueError, parse_abi_value, "uint256", "1.12345e4")
assert parse_abi_value("uint256", "1.12345e5") == 112345
assert pytest.raises(ValueError, parse_abi_value, "1.1", "uint256")
assert pytest.raises(ValueError, parse_abi_value, "1.12345e1", "uint256")
assert pytest.raises(ValueError, parse_abi_value, "1.12345e2", "uint256")
assert pytest.raises(ValueError, parse_abi_value, "1.12345e3", "uint256")
assert pytest.raises(ValueError, parse_abi_value, "1.12345e4", "uint256")
assert parse_abi_value("1.12345e5", "uint256") == 112345


def test_parse_abi_value_bool() -> None:
assert parse_abi_value("bool", "0") is False
assert parse_abi_value("bool", "1") is True
assert parse_abi_value("bool", "false") is False
assert parse_abi_value("bool", "true") is True
assert parse_abi_value("bool", "False") is False
assert parse_abi_value("bool", "True") is True
assert parse_abi_value("bool", "FALSE") is False
assert parse_abi_value("bool", "TRUE") is True
assert parse_abi_value("bool", "False ") is False
assert parse_abi_value("bool", " True") is True
assert parse_abi_value("bool", " FALSE") is False
assert parse_abi_value("bool", "TRUE ") is True
assert parse_abi_value("bool", " False ") is False
assert parse_abi_value("bool", " True ") is True
assert parse_abi_value("bool", " FALSE ") is False
assert parse_abi_value("bool", "TRUE ") is True
assert pytest.raises(ValueError, parse_abi_value, "bool", "2")
assert pytest.raises(ValueError, parse_abi_value, "bool", "3")
assert parse_abi_value("0", "bool") is False
assert parse_abi_value("1", "bool") is True
assert parse_abi_value("false", "bool") is False
assert parse_abi_value("true", "bool") is True
assert parse_abi_value("False", "bool") is False
assert parse_abi_value("True", "bool") is True
assert parse_abi_value("FALSE", "bool") is False
assert parse_abi_value("TRUE", "bool") is True
assert parse_abi_value("False ", "bool") is False
assert parse_abi_value(" True", "bool") is True
assert parse_abi_value(" FALSE", "bool") is False
assert parse_abi_value("TRUE ", "bool") is True
assert parse_abi_value(" False ", "bool") is False
assert parse_abi_value(" True ", "bool") is True
assert parse_abi_value(" FALSE ", "bool") is False
assert parse_abi_value("TRUE ", "bool") is True
assert pytest.raises(ValueError, parse_abi_value, "2", "bool")
assert pytest.raises(ValueError, parse_abi_value, "3", "bool")


def test_parse_abi_value_address() -> None:
assert parse_abi_value("address", "0x0000000000000000000000000000000000000000") == (
assert parse_abi_value("0x0000000000000000000000000000000000000000", "address") == (
"0x0000000000000000000000000000000000000000"
)
assert parse_abi_value("address", "0xdac17f958d2ee523a2206206994597c13d831ec7") == (
assert parse_abi_value("0xdac17f958d2ee523a2206206994597c13d831ec7", "address") == (
"0xdAC17F958D2ee523a2206206994597C13D831ec7"
)
assert pytest.raises(ValueError, parse_abi_value, "address", "0x0000000")
assert pytest.raises(ValueError, parse_abi_value, "0x0000000", "address")
assert pytest.raises(
InvalidAddress,
parse_abi_value,
"address",
"0xdac17f958d2ee523a2206206994597c13d831ec7",
"address",
checksum_addresses=False,
)

Expand All @@ -192,59 +194,114 @@ def resolve_fn(name: str) -> str:
return "0x0000000000000000000000000000000000000002"
return name

assert parse_abi_value("address", "alice", resolve_address_fn=resolve_fn) == (
assert parse_abi_value("alice", "address", resolve_address_fn=resolve_fn) == (
"0x0000000000000000000000000000000000000001"
)

assert parse_abi_value("address", "bob", resolve_address_fn=resolve_fn) == (
assert parse_abi_value("bob", "address", resolve_address_fn=resolve_fn) == (
"0x0000000000000000000000000000000000000002"
)

assert parse_abi_value("address[]", "alice,bob", resolve_address_fn=resolve_fn) == (
assert parse_abi_value("alice,bob", "address[]", resolve_address_fn=resolve_fn) == (
[
"0x0000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000002",
]
)

assert parse_abi_value(
"address",
"0x0000000000000000000000000000000000000003",
"address",
resolve_address_fn=resolve_fn,
) == ("0x0000000000000000000000000000000000000003")


def test_parse_abi_value_array_csv() -> None:
assert parse_abi_value("bool[]", "True,False,true,false,1,0") == [
assert parse_abi_value("True,False,true,false,1,0", "bool[]") == [
True,
False,
True,
False,
True,
False,
]
assert parse_abi_value("int256[]", "-2,-1,0,1,2") == [-2, -1, 0, 1, 2]
assert parse_abi_value("uint256[]", "0,1,2,3,4") == [0, 1, 2, 3, 4]
assert parse_abi_value("string[]", "0,1,2,3,4") == ["0", "1", "2", "3", "4"]
assert parse_abi_value("string[]", "hello,world") == ["hello", "world"]
assert parse_abi_value("string[]", 'hello,"w,o,r,l,d"') == ["hello", "w,o,r,l,d"]
assert parse_abi_value("-2,-1,0,1,2", "int256[]") == [-2, -1, 0, 1, 2]
assert parse_abi_value("0,1,2,3,4", "uint256[]") == [0, 1, 2, 3, 4]
assert parse_abi_value("0,1,2,3,4", "string[]") == ["0", "1", "2", "3", "4"]
assert parse_abi_value("hello,world", "string[]") == ["hello", "world"]
assert parse_abi_value('hello,"w,o,r,l,d"', "string[]") == ["hello", "w,o,r,l,d"]
with pytest.raises(NotSupportedYet):
parse_abi_value("whatever", "string[][]")


def test_parse_abi_value_tuple_csv() -> None:
abi = cast(
ABIFunctionParams,
{
"name": "TestTuple",
"type": "tuple",
"components": [
{"name": "TestBool", "type": "bool"},
{"name": "TestInt", "type": "int256"},
{"name": "TestUint", "type": "uint256"},
{"name": "TestString", "type": "string"},
{"name": "TestAddress", "type": "address"},
],
},
)
assert parse_abi_value(
"True,-123,123,hello,0xdAC17F958D2ee523a2206206994597C13D831ec7",
abi_input=abi,
) == {
"TestBool": True,
"TestInt": -123,
"TestUint": 123,
"TestString": "hello",
"TestAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
}
with pytest.raises(ValueError):
parse_abi_value("whatever", abi_type="tuple")
with pytest.raises(
Web3CliError, match="Provided 4 values for tuple argument TestTuple, expected 5"
):
assert parse_abi_value("True,-123,123,hello", abi_input=abi)
with pytest.raises(NotSupportedYet, match="Tuple of arrays not supported"):
nested_abi = cast(
ABIFunctionParams,
{
"name": "TestTuple",
"type": "tuple",
"components": [{"name": "TestSubArray", "type": "string[]"}],
},
)
parse_abi_value("whatever", abi_input=nested_abi)
with pytest.raises(NotSupportedYet, match="Tuple of tuples not supported"):
nested_abi = cast(
ABIFunctionParams,
{
"name": "TestTuple",
"type": "tuple",
"components": [{"name": "TestSubTuple", "type": "tuple"}],
},
)
parse_abi_value("whatever", abi_input=nested_abi)


def test_parse_abi_value_string() -> None:
assert parse_abi_value("string", "hello") == "hello"
assert parse_abi_value("string", "hello world") == "hello world"
assert parse_abi_value("hello", "string") == "hello"
assert parse_abi_value("hello world", "string") == "hello world"
assert (
parse_abi_value("string", "0xdAC17F958D2ee523a2206206994597C13D831ec7")
parse_abi_value("0xdAC17F958D2ee523a2206206994597C13D831ec7", "string")
== "0xdAC17F958D2ee523a2206206994597C13D831ec7"
)
assert parse_abi_value("string", "3") == "3"
assert parse_abi_value("string", "False") == "False"
assert parse_abi_value("3", "string") == "3"
assert parse_abi_value("False", "string") == "False"


def test_parse_abi_value_bytes() -> None:
assert parse_abi_value("bytes", "0") == HexBytes("0")
assert parse_abi_value("bytes", "123") == HexBytes("123")
assert pytest.raises(Web3CliError, parse_abi_value, "bytes", "q")
assert parse_abi_value("0", "bytes") == HexBytes("0")
assert parse_abi_value("123", "bytes") == HexBytes("123")
assert pytest.raises(Web3CliError, parse_abi_value, "q", "bytes")


def test_decode_function_data(erc20_abi: ABI) -> None:
Expand Down

0 comments on commit 6286615

Please sign in to comment.