Skip to content

Commit

Permalink
add tests for nested structs
Browse files Browse the repository at this point in the history
  • Loading branch information
tserg committed Feb 17, 2022
1 parent 67904b9 commit dd793c7
Show file tree
Hide file tree
Showing 3 changed files with 335 additions and 0 deletions.
56 changes: 56 additions & 0 deletions tests/ast/test_folding.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,62 @@ def test_replace_userdefined_struct_member(source):
assert vy_ast.compare_nodes(l_ast, r_ast)


userdefined_nested_struct = [
("b: Foo = FOO", "b: Foo = Foo({f1: Bar({b1: 123, b2: 456}), f2: 789})")
]


@pytest.mark.parametrize("source", userdefined_nested_struct)
def test_replace_userdefined_nested_struct(source):
preamble = """
struct Bar:
b1: uint256
b2: uint256
struct Foo:
f1: Bar
f2: uint256
FOO: constant(Foo) = Foo({f1: Bar({b1: 123, b2: 456}), f2: 789})
"""
l_source = f"{preamble}\n{source[0]}"
r_source = f"{preamble}\n{source[1]}"

l_ast = vy_ast.parse_to_ast(l_source)
folding.replace_user_defined_constants(l_ast)

r_ast = vy_ast.parse_to_ast(r_source)

assert vy_ast.compare_nodes(l_ast, r_ast)


userdefined_nested_struct_member = [("b: uint256 = FOO.f1.b1", "b: uint256 = 123")]


@pytest.mark.parametrize("source", userdefined_nested_struct_member)
def test_replace_userdefined_nested_struct_member(source):
preamble = """
struct Bar:
b1: uint256
b2: uint256
struct Foo:
f1: Bar
f2: uint256
FOO: constant(Foo) = Foo({f1: Bar({b1: 123, b2: 456}), f2: 789})
"""
l_source = f"{preamble}\n{source[0]}"
r_source = f"{preamble}\n{source[1]}"

l_ast = vy_ast.parse_to_ast(l_source)
folding.replace_user_defined_constants(l_ast)

r_ast = vy_ast.parse_to_ast(r_source)

assert vy_ast.compare_nodes(l_ast, r_ast)


builtin_folding_functions = [("ceil(4.2)", "5"), ("floor(4.2)", "4")]

builtin_folding_sources = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1830,6 +1830,269 @@ def test(addr: address) -> int128:
assert c2.test(c1.address) == 1


def test_constant_nested_struct_return_external_contract_call_1(get_contract_with_gas_estimation):
contract_1 = """
struct X:
x: int128
y: address
struct A:
a: X
b: uint256
BAR: constant(A) = A({a: X({x: 1, y: 0x0000000000000000000000000000000000012345}), b: 777})
@external
def out_literals() -> A:
return BAR
"""

contract_2 = """
struct X:
x: int128
y: address
struct A:
a: X
b: uint256
interface Test:
def out_literals() -> A : view
@external
def test(addr: address) -> (X, uint256):
ret: A = Test(addr).out_literals()
return ret.a, ret.b
"""
c1 = get_contract_with_gas_estimation(contract_1)
c2 = get_contract_with_gas_estimation(contract_2)

assert c1.out_literals() == ((1, "0x0000000000000000000000000000000000012345"), 777)
assert c2.test(c1.address) == list(c1.out_literals())


@pytest.mark.parametrize("i,ln,s,", [(100, 6, "abcde"), (41, 40, "a" * 34), (57, 70, "z" * 68)])
def test_constant_nested_struct_return_external_contract_call_2(
get_contract_with_gas_estimation, i, ln, s
):
contract_1 = f"""
struct X:
x: int128
y: String[{ln}]
z: Bytes[{ln}]
struct A:
a: X
b: uint256
BAR: constant(A) = A({{a: X({{x: {i}, y: "{s}", z: b"{s}"}}), b: 777}})
@external
def get_struct_a() -> A:
return BAR
"""

contract_2 = f"""
struct X:
x: int128
y: String[{ln}]
z: Bytes[{ln}]
struct A:
a: X
b: uint256
interface Test:
def get_struct_a() -> A : view
@external
def test(addr: address) -> (X, uint256):
ret: A = Test(addr).get_struct_a()
return ret.a, ret.b
"""
c1 = get_contract_with_gas_estimation(contract_1)
c2 = get_contract_with_gas_estimation(contract_2)

assert c1.get_struct_a() == ((i, s, bytes(s, "utf-8")), 777)
assert c2.test(c1.address) == list(c1.get_struct_a())


def test_constant_nested_struct_return_external_contract_call_3(get_contract_with_gas_estimation):
contract_1 = """
struct X:
x: int128
y: int128
struct A:
a: X
b: uint256
struct C:
c: A
d: bool
BAR: constant(C) = C({c: A({a: X({x: 1, y: -1}), b: 777}), d: True})
@external
def out_literals() -> C:
return BAR
"""

contract_2 = """
struct X:
x: int128
y: int128
struct A:
a: X
b: uint256
struct C:
c: A
d: bool
interface Test:
def out_literals() -> C : view
@external
def test(addr: address) -> (A, bool):
ret: C = Test(addr).out_literals()
return ret.c, ret.d
"""
c1 = get_contract_with_gas_estimation(contract_1)
c2 = get_contract_with_gas_estimation(contract_2)

assert c1.out_literals() == (((1, -1), 777), True)
assert c2.test(c1.address) == list(c1.out_literals())


def test_constant_nested_struct_member_return_external_contract_call_1(
get_contract_with_gas_estimation,
):
contract_1 = """
struct X:
x: int128
y: address
struct A:
a: X
b: uint256
BAR: constant(A) = A({a: X({x: 1, y: 0x0000000000000000000000000000000000012345}), b: 777})
@external
def get_y() -> address:
return BAR.a.y
"""

contract_2 = """
interface Test:
def get_y() -> address : view
@external
def test(addr: address) -> address:
ret: address = Test(addr).get_y()
return ret
"""
c1 = get_contract_with_gas_estimation(contract_1)
c2 = get_contract_with_gas_estimation(contract_2)

assert c1.get_y() == "0x0000000000000000000000000000000000012345"
assert c2.test(c1.address) == "0x0000000000000000000000000000000000012345"


@pytest.mark.parametrize("i,ln,s,", [(100, 6, "abcde"), (41, 40, "a" * 34), (57, 70, "z" * 68)])
def test_constant_nested_struct_member_return_external_contract_call_2(
get_contract_with_gas_estimation, i, ln, s
):
contract_1 = f"""
struct X:
x: int128
y: String[{ln}]
z: Bytes[{ln}]
struct A:
a: X
b: uint256
c: bool
BAR: constant(A) = A({{a: X({{x: {i}, y: "{s}", z: b"{s}"}}), b: 777, c: True}})
@external
def get_y() -> String[{ln}]:
return BAR.a.y
"""

contract_2 = f"""
interface Test:
def get_y() -> String[{ln}] : view
@external
def test(addr: address) -> String[{ln}]:
ret: String[{ln}] = Test(addr).get_y()
return ret
"""
c1 = get_contract_with_gas_estimation(contract_1)
c2 = get_contract_with_gas_estimation(contract_2)

assert c1.get_y() == s
assert c2.test(c1.address) == s


def test_constant_nested_struct_member_return_external_contract_call_3(
get_contract_with_gas_estimation,
):
contract_1 = """
struct X:
x: int128
y: int128
struct A:
a: X
b: uint256
struct C:
c: A
d: bool
BAR: constant(C) = C({c: A({a: X({x: 1, y: -1}), b: 777}), d: True})
@external
def get_y() -> int128:
return BAR.c.a.y
@external
def get_b() -> uint256:
return BAR.c.b
"""

contract_2 = """
interface Test:
def get_y() -> int128 : view
def get_b() -> uint256 : view
@external
def test(addr: address) -> int128:
ret: int128 = Test(addr).get_y()
return ret
@external
def test2(addr: address) -> uint256:
ret: uint256 = Test(addr).get_b()
return ret
"""
c1 = get_contract_with_gas_estimation(contract_1)
c2 = get_contract_with_gas_estimation(contract_2)

assert c1.get_y() == -1
assert c2.test(c1.address) == -1

assert c1.get_b() == 777
assert c2.test2(c1.address) == 777


def test_dynamically_sized_struct_external_contract_call(get_contract_with_gas_estimation):
contract_1 = """
struct X:
Expand Down
16 changes: 16 additions & 0 deletions tests/parser/syntax/test_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,22 @@ def deposit(deposit_input: Bytes[2048]):
CONST_BAR: constant(Foo) = Foo({a: A, b: B})
""",
"""
struct Foo:
a: uint256
b: uint256
struct Bar:
c: Foo
d: int128
A: constant(uint256) = 1
B: constant(uint256) = 2
C: constant(Foo) = Foo({a: A, b: B})
D: constant(int128) = -1
CONST_BAR: constant(Bar) = Bar({c: C, d: D})
""",
]


Expand Down

0 comments on commit dd793c7

Please sign in to comment.