Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: fix test for slice #3633

Merged
merged 11 commits into from
Nov 2, 2023
50 changes: 37 additions & 13 deletions tests/parser/functions/test_slice.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,23 @@ def test_slice_bytes(
literal_length,
length_bound,
):
preamble = ""
if location == "memory":
spliced_code = f"foo: Bytes[{length_bound}] = inp"
foo = "foo"
elif location == "storage":
preamble = f"""
foo: Bytes[{length_bound}]
"""
spliced_code = "self.foo = inp"
foo = "self.foo"
elif location == "code":
preamble = f"""
IMMUTABLE_BYTES: immutable(Bytes[{length_bound}])
@external
def __init__(foo: Bytes[{length_bound}]):
IMMUTABLE_BYTES = foo
"""
spliced_code = ""
foo = "IMMUTABLE_BYTES"
elif location == "literal":
Expand All @@ -127,11 +137,7 @@ def test_slice_bytes(
_length = length if literal_length else "length"

code = f"""
foo: Bytes[{length_bound}]
IMMUTABLE_BYTES: immutable(Bytes[{length_bound}])
@external
def __init__(foo: Bytes[{length_bound}]):
IMMUTABLE_BYTES = foo
{preamble}

@external
def do_slice(inp: Bytes[{length_bound}], start: uint256, length: uint256) -> Bytes[{length_bound}]:
Expand All @@ -143,23 +149,41 @@ def _get_contract():
return get_contract(code, bytesdata, override_opt_level=opt_level)

data_length = len(bytesdata) if location == "literal" else length_bound
end = start + length

is_zero_literal_length = literal_length and length < 1
literal_start_exceeds_data_length = literal_start and start > data_length
literal_length_exceeds_data = (literal_length and length > data_length) or (
end > data_length and literal_start and literal_length
)

data_longer_than_length_bound = len(bytesdata) > length_bound
# `not literal_length` condition catches this contract:
# @external
# def do_slice(inp: Bytes[1], start: uint256, length: uint256) -> Bytes[1]:
# return slice(b'\x00\x00', 0, length)
Fixed Show fixed Hide fixed
invalid_slice_literal = (
location == "literal"
and data_longer_than_length_bound
and ((literal_length and length > length_bound) or not literal_length)
)

if (
(start + length > data_length and literal_start and literal_length)
or (literal_length and length > data_length)
or (location == "literal" and len(bytesdata) > length_bound)
or (literal_start and start > data_length)
or (literal_length and length < 1)
is_zero_literal_length
or literal_start_exceeds_data_length
or literal_length_exceeds_data
or invalid_slice_literal
):
assert_compile_failed(lambda: _get_contract(), (ArgumentException, TypeMismatch))
elif len(bytesdata) > data_length:
elif location == "code" and data_longer_than_length_bound:
# deploy fail
assert_tx_failed(lambda: _get_contract())
elif start + length > len(bytesdata):
elif end > len(bytesdata) or data_longer_than_length_bound:
c = _get_contract()
assert_tx_failed(lambda: c.do_slice(bytesdata, start, length))
else:
c = _get_contract()
assert c.do_slice(bytesdata, start, length) == bytesdata[start : start + length], code
assert c.do_slice(bytesdata, start, length) == bytesdata[start:end], code


def test_slice_private(get_contract):
Expand Down