Skip to content

Commit

Permalink
cr from original strings pr
Browse files Browse the repository at this point in the history
  • Loading branch information
barnjamin committed Apr 21, 2022
1 parent 190ec16 commit 33ce682
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 63 deletions.
3 changes: 3 additions & 0 deletions pyteal/ast/abi/address.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ def new_instance(self) -> "Address":
def __str__(self) -> str:
return "address"

def __eq__(self, other: object) -> bool:
return isinstance(other, AddressTypeSpec)


AddressTypeSpec.__module__ = "pyteal"

Expand Down
84 changes: 55 additions & 29 deletions pyteal/ast/abi/address_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from ... import *
import pytest

options = CompileOptions(version=5)
import pyteal as pt
from pyteal import abi
from .util import substringForDecoding

options = pt.CompileOptions(version=5)


def test_AddressTypeSpec_str():
Expand All @@ -23,8 +27,8 @@ def test_AddressTypeSpec_eq():
assert abi.AddressTypeSpec() == abi.AddressTypeSpec()

for otherType in (
abi.ByteTypeSpec,
abi.StaticArrayTypeSpec(abi.ByteTypeSpec(), 31),
abi.ByteTypeSpec(),
abi.StaticArrayTypeSpec(abi.ByteTypeSpec(), 32),
abi.DynamicArrayTypeSpec(abi.ByteTypeSpec()),
):
assert abi.AddressTypeSpec() != otherType
Expand All @@ -33,44 +37,66 @@ def test_AddressTypeSpec_eq():
def test_Address_encode():
value = abi.Address()
expr = value.encode()
assert expr.type_of() == TealType.bytes
assert expr.type_of() == pt.TealType.bytes
assert expr.has_return() is False

expected = TealSimpleBlock([TealOp(expr, Op.load, value.stored_value.slot)])
expected = pt.TealSimpleBlock(
[pt.TealOp(expr, pt.Op.load, value.stored_value.slot)]
)
actual, _ = expr.__teal__(options)
assert actual == expected


def test_Address_decode():
from os import urandom

value = abi.Address()
for value_to_set in [urandom(abi.ADDRESS_LENGTH) for x in range(10)]:
expr = value.decode(Bytes(value_to_set))

assert expr.type_of() == TealType.none
assert expr.has_return() is False

expected = TealSimpleBlock(
[
TealOp(None, Op.byte, f"0x{value_to_set.hex()}"),
TealOp(None, Op.store, value.stored_value.slot),
]
)
actual, _ = expr.__teal__(options)
actual.addIncoming()
actual = TealBlock.NormalizeBlocks(actual)

with TealComponent.Context.ignoreExprEquality():
assert actual == expected
address = bytes([0] * abi.ADDRESS_LENGTH)
encoded = pt.Bytes(address)

for startIndex in (None, pt.Int(0)):
for endIndex in (None, pt.Int(1)):
for length in (None, pt.Int(2)):
value = abi.Address()

if endIndex is not None and length is not None:
with pytest.raises(pt.TealInputError):
value.decode(
encoded,
startIndex=startIndex,
endIndex=endIndex,
length=length,
)
continue

expr = value.decode(
encoded, startIndex=startIndex, endIndex=endIndex, length=length
)
assert expr.type_of() == pt.TealType.none
assert expr.has_return() is False

expectedExpr = value.stored_value.store(
substringForDecoding(
encoded, startIndex=startIndex, endIndex=endIndex, length=length
)
)
expected, _ = expectedExpr.__teal__(options)
expected.addIncoming()
expected = pt.TealBlock.NormalizeBlocks(expected)

actual, _ = expr.__teal__(options)
actual.addIncoming()
actual = pt.TealBlock.NormalizeBlocks(actual)

with pt.TealComponent.Context.ignoreExprEquality():
assert actual == expected


def test_Address_get():
value = abi.Address()
expr = value.get()
assert expr.type_of() == TealType.bytes
assert expr.type_of() == pt.TealType.bytes
assert expr.has_return() is False

expected = TealSimpleBlock([TealOp(expr, Op.load, value.stored_value.slot)])
expected = pt.TealSimpleBlock(
[pt.TealOp(expr, pt.Op.load, value.stored_value.slot)]
)
actual, _ = expr.__teal__(options)
assert actual == expected
8 changes: 7 additions & 1 deletion pyteal/ast/abi/string.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def encoded_string(s: Expr):
from .uint import ByteTypeSpec, Uint16TypeSpec
from .util import substringForDecoding

from ..substring import Suffix
from ..int import Int
from ..expr import Expr

Expand All @@ -39,6 +40,9 @@ def new_instance(self) -> "String":
def __str__(self) -> str:
return "string"

def __eq__(self, other: object) -> bool:
return isinstance(other, StringTypeSpec)


StringTypeSpec.__module__ = "pyteal"

Expand All @@ -51,7 +55,9 @@ def type_spec(self) -> StringTypeSpec:
return StringTypeSpec()

def get(self) -> Expr:
return substringForDecoding(self.stored_value.load(), startIndex=Int(2))
return Suffix(
self.stored_value.load(), Int(Uint16TypeSpec().byte_length_static())
)

def set(self, value: Union[str, "String", ComputedValue["String"], Expr]) -> Expr:

Expand Down
93 changes: 60 additions & 33 deletions pyteal/ast/abi/string_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from ... import *
import pytest

options = CompileOptions(version=5)
import pyteal as pt
from pyteal import abi
from .util import substringForDecoding


options = pt.CompileOptions(version=5)


def test_StringTypeSpec_str():
Expand All @@ -19,61 +24,83 @@ def test_StringTypeSpec_eq():
assert abi.StringTypeSpec() == abi.StringTypeSpec()

for otherType in (
abi.ByteTypeSpec,
abi.ByteTypeSpec(),
abi.StaticArrayTypeSpec(abi.ByteTypeSpec(), 1),
abi.DynamicArrayTypeSpec(abi.Uint8TypeSpec()),
abi.DynamicArrayTypeSpec(abi.ByteTypeSpec()),
):
assert abi.StringTypeSpec() != otherType


def test_String_encode():
value = abi.String()
expr = value.encode()
assert expr.type_of() == TealType.bytes
assert expr.type_of() == pt.TealType.bytes
assert expr.has_return() is False

expected = TealSimpleBlock([TealOp(expr, Op.load, value.stored_value.slot)])
expected = pt.TealSimpleBlock(
[pt.TealOp(expr, pt.Op.load, value.stored_value.slot)]
)
actual, _ = expr.__teal__(options)
assert actual == expected


def test_String_decode():
import random
from os import urandom

value = abi.String()
for value_to_set in [urandom(random.randint(0, 50)) for x in range(10)]:
expr = value.decode(Bytes(value_to_set))

assert expr.type_of() == TealType.none
assert expr.has_return() is False

expected = TealSimpleBlock(
[
TealOp(None, Op.byte, f"0x{value_to_set.hex()}"),
TealOp(None, Op.store, value.stored_value.slot),
]
)
actual, _ = expr.__teal__(options)
actual.addIncoming()
actual = TealBlock.NormalizeBlocks(actual)

with TealComponent.Context.ignoreExprEquality():
assert actual == expected
def test_DynamicArray_decode():
encoded = pt.Bytes("encoded")
stringType = abi.StringTypeSpec()
for startIndex in (None, pt.Int(1)):
for endIndex in (None, pt.Int(2)):
for length in (None, pt.Int(3)):
value = stringType.new_instance()

if endIndex is not None and length is not None:
with pytest.raises(pt.TealInputError):
value.decode(
encoded,
startIndex=startIndex,
endIndex=endIndex,
length=length,
)
continue

expr = value.decode(
encoded, startIndex=startIndex, endIndex=endIndex, length=length
)
assert expr.type_of() == pt.TealType.none
assert not expr.has_return()

expectedExpr = value.stored_value.store(
substringForDecoding(
encoded, startIndex=startIndex, endIndex=endIndex, length=length
)
)
expected, _ = expectedExpr.__teal__(options)
expected.addIncoming()
expected = pt.TealBlock.NormalizeBlocks(expected)

actual, _ = expr.__teal__(options)
actual.addIncoming()
actual = pt.TealBlock.NormalizeBlocks(actual)

with pt.TealComponent.Context.ignoreExprEquality():
assert actual == expected


def test_String_get():
value = abi.String()
expr = value.get()
assert expr.type_of() == TealType.bytes
assert expr.type_of() == pt.TealType.bytes
assert expr.has_return() is False

expected = TealSimpleBlock(
[TealOp(expr, Op.load, value.stored_value.slot), TealOp(None, Op.extract, 2, 0)]
expected = pt.TealSimpleBlock(
[
pt.TealOp(expr, pt.Op.load, value.stored_value.slot),
pt.TealOp(None, pt.Op.extract, 2, 0),
]
)
actual, _ = expr.__teal__(options)
actual.addIncoming()
actual = TealBlock.NormalizeBlocks(actual)
actual = pt.TealBlock.NormalizeBlocks(actual)

with TealComponent.Context.ignoreExprEquality():
with pt.TealComponent.Context.ignoreExprEquality():
assert actual == expected

0 comments on commit 33ce682

Please sign in to comment.