def test_err(): expr = pt.Err() assert expr.type_of() == pt.TealType.none assert expr.has_return() expected = pt.TealSimpleBlock([pt.TealOp(expr, pt.Op.err)]) actual, _ = expr.__teal__(pt.CompileOptions()) assert actual == expected
def test_method(): expr = MethodSignature("add(uint64,uint64)uint64") assert expr.type_of() == pt.TealType.bytes expected = pt.TealSimpleBlock([ pt.TealOp(expr, pt.Op.method_signature, '"add(uint64,uint64)uint64"') ]) actual, _ = expr.__teal__(pt.CompileOptions()) assert expected == actual
def test_addr(): expr = pt.Addr("NJUWK3DJNZTWU2LFNRUW4Z3KNFSWY2LOM5VGSZLMNFXGO2TJMVWGS3THMF") assert expr.type_of() == pt.TealType.bytes expected = pt.TealSimpleBlock( [ pt.TealOp( expr, pt.Op.addr, "NJUWK3DJNZTWU2LFNRUW4Z3KNFSWY2LOM5VGSZLMNFXGO2TJMVWGS3THMF", ) ] ) actual, _ = expr.__teal__(pt.CompileOptions()) assert actual == expected
import pytest import pyteal as pt from pyteal.ast.comment import CommentExpr options = pt.CompileOptions() def test_CommentExpr(): for comment in ("", "hello world", " // a b c // \t . "): expr = CommentExpr(comment) assert expr.comment == comment assert expr.type_of() == pt.TealType.none assert expr.has_return() is False expected = pt.TealSimpleBlock([ pt.TealOp(expr, pt.Op.comment, comment), ]) actual, _ = expr.__teal__(options) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) assert actual == expected for newline in ("\n", "\r\n", "\r"): with pytest.raises( pt.TealInputError, match= r"Newlines should not be present in the CommentExpr constructor$", ):
import pytest import pyteal as pt avm2Options = pt.CompileOptions(version=2) avm3Options = pt.CompileOptions(version=3) avm5Options = pt.CompileOptions(version=5) avm6Options = pt.CompileOptions(version=6) def test_global_min_txn_fee(): expr = pt.Global.min_txn_fee() assert expr.type_of() == pt.TealType.uint64 expected = pt.TealSimpleBlock( [pt.TealOp(expr, pt.Op.global_, "MinTxnFee")]) actual, _ = expr.__teal__(avm2Options) assert actual == expected def test_global_min_balance(): expr = pt.Global.min_balance() assert expr.type_of() == pt.TealType.uint64 expected = pt.TealSimpleBlock( [pt.TealOp(expr, pt.Op.global_, "MinBalance")]) actual, _ = expr.__teal__(avm2Options)
import pytest import pyteal as pt avm3Options = pt.CompileOptions(version=3) avm4Options = pt.CompileOptions(version=4) def test_gaid_teal_3(): with pytest.raises(pt.TealInputError): pt.GeneratedID(0).__teal__(avm3Options) def test_gaid(): expr = pt.GeneratedID(0) assert expr.type_of() == pt.TealType.uint64 expected = pt.TealSimpleBlock([pt.TealOp(expr, pt.Op.gaid, 0)]) actual, _ = expr.__teal__(avm4Options) assert actual == expected def test_gaid_invalid(): with pytest.raises(pt.TealInputError): pt.GeneratedID(-1) with pytest.raises(pt.TealInputError): pt.GeneratedID(pt.MAX_GROUP_SIZE)
import pytest import pyteal as pt avm6Options = pt.CompileOptions(version=6) def test_gtxn_invalid(): for f, e in [ (lambda: pt.Gtxn[-1], pt.TealInputError), (lambda: pt.Gtxn[pt.MAX_GROUP_SIZE + 1], pt.TealInputError), (lambda: pt.Gtxn[pt.Pop(pt.Int(0))], pt.TealTypeError), (lambda: pt.Gtxn[pt.Bytes("index")], pt.TealTypeError), ]: with pytest.raises(e): f() def test_gtxn_expr_invalid(): for f, e in [ ( lambda: pt.GtxnExpr(pt.Assert(pt.Int(1)), pt.TxnField.sender), pt.TealTypeError, ), ]: with pytest.raises(e): f() def test_gtxn_expr_valid(): [
import pytest import pyteal as pt from pyteal.ast.maybe_test import assert_MaybeValue_equality options = pt.CompileOptions() avm4Options = pt.CompileOptions(version=4) avm5Options = pt.CompileOptions(version=5) def test_on_complete(): assert pt.OnComplete.NoOp.__teal__(options)[0] == pt.TealSimpleBlock( [pt.TealOp(pt.OnComplete.NoOp, pt.Op.int, "NoOp")]) assert pt.OnComplete.OptIn.__teal__(options)[0] == pt.TealSimpleBlock( [pt.TealOp(pt.OnComplete.OptIn, pt.Op.int, "OptIn")]) assert pt.OnComplete.CloseOut.__teal__(options)[0] == pt.TealSimpleBlock( [pt.TealOp(pt.OnComplete.CloseOut, pt.Op.int, "CloseOut")]) assert pt.OnComplete.ClearState.__teal__(options)[0] == pt.TealSimpleBlock( [pt.TealOp(pt.OnComplete.ClearState, pt.Op.int, "ClearState")]) assert pt.OnComplete.UpdateApplication.__teal__( options)[0] == pt.TealSimpleBlock([ pt.TealOp(pt.OnComplete.UpdateApplication, pt.Op.int, "UpdateApplication") ]) assert pt.OnComplete.DeleteApplication.__teal__( options)[0] == pt.TealSimpleBlock([
import pytest import pyteal as pt avm2Options = pt.CompileOptions(version=2) avm3Options = pt.CompileOptions(version=3) def test_teal_2_assert(): arg = pt.Int(1) expr = pt.Assert(arg) assert expr.type_of() == pt.TealType.none expected, _ = arg.__teal__(avm2Options) expectedBranch = pt.TealConditionalBlock([]) expectedBranch.setTrueBlock(pt.TealSimpleBlock([])) expectedBranch.setFalseBlock(pt.Err().__teal__(avm2Options)[0]) expected.setNextBlock(expectedBranch) actual, _ = expr.__teal__(avm2Options) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected def test_teal_2_assert_multi(): args = [pt.Int(1), pt.Int(2)] expr = pt.Assert(*args) assert expr.type_of() == pt.TealType.none firstAssert = pt.Assert(args[0])
import pyteal as pt from pyteal import abi options = pt.CompileOptions(version=5) class ContainerType(abi.ComputedValue): def __init__(self, type_spec: abi.TypeSpec, encodings: pt.Expr): self.type_spec = type_spec self.encodings = encodings def produced_type_spec(self) -> abi.TypeSpec: return self.type_spec def store_into(self, output: abi.BaseType) -> pt.Expr: if output.type_spec() != self.type_spec: raise pt.TealInputError( f"expected type_spec {self.type_spec} but get {output.type_spec()}" ) return output.stored_value.store(self.encodings) def test_ComputedType_use(): for value in (0, 1, 2, 3, 12345): dummyComputedType = ContainerType(abi.Uint64TypeSpec(), pt.Int(value)) expr = dummyComputedType.use(lambda output: pt.Int(2) * output.get()) assert expr.type_of() == pt.TealType.uint64 assert not expr.has_return() actual, _ = expr.__teal__(options) actual.addIncoming()
def test_txn_fields(): dynamicGtxnArg = pt.Int(0) txnObjects = [ (pt.Txn, pt.Op.txn, pt.Op.txna, pt.Op.txnas, [], []), *[ (pt.Gtxn[i], pt.Op.gtxn, pt.Op.gtxna, pt.Op.gtxnas, [i], []) for i in range(pt.MAX_GROUP_SIZE) ], ( pt.Gtxn[dynamicGtxnArg], pt.Op.gtxns, pt.Op.gtxnsa, pt.Op.gtxnsas, [], [pt.TealOp(dynamicGtxnArg, pt.Op.int, 0)], ), (pt.InnerTxn, pt.Op.itxn, pt.Op.itxna, pt.Op.itxnas, [], []), *[ (pt.Gitxn[i], pt.Op.gitxn, pt.Op.gitxna, pt.Op.gitxnas, [i], []) for i in range(pt.MAX_GROUP_SIZE) ], ] for ( txnObject, op, staticArrayOp, dynamicArrayOp, immediateArgsPrefix, irPrefix, ) in txnObjects: for field in pt.TxnField: if field.is_array: array = arrayFieldToProperty[field](txnObject) lengthExpr = array.length() lengthFieldName = arrayFieldToLengthField[field].arg_name immediateArgs = immediateArgsPrefix + [lengthFieldName] expected = pt.TealSimpleBlock( irPrefix + [pt.TealOp(lengthExpr, op, *immediateArgs)] ) expected.addIncoming() expected = pt.TealBlock.NormalizeBlocks(expected) version = max(op.min_version, field.min_version) actual, _ = lengthExpr.__teal__(pt.CompileOptions(version=version)) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) assert ( actual == expected ), "{}: array length for field {} does not match expected".format( op, field ) if version > 2: with pytest.raises(pt.TealInputError): lengthExpr.__teal__(pt.CompileOptions(version=version - 1)) for i in range(32): # just an arbitrary large int elementExpr = array[i] immediateArgs = immediateArgsPrefix + [field.arg_name, i] expected = pt.TealSimpleBlock( irPrefix + [pt.TealOp(elementExpr, staticArrayOp, *immediateArgs)] ) expected.addIncoming() expected = pt.TealBlock.NormalizeBlocks(expected) version = max(staticArrayOp.min_version, field.min_version) actual, _ = elementExpr.__teal__(pt.CompileOptions(version=version)) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) assert ( actual == expected ), "{}: static array field {} does not match expected".format( staticArrayOp, field ) if version > 2: with pytest.raises(pt.TealInputError): elementExpr.__teal__(pt.CompileOptions(version=version - 1)) if dynamicArrayOp is not None: dynamicIndex = pt.Int(2) dynamicElementExpr = array[dynamicIndex] immediateArgs = immediateArgsPrefix + [field.arg_name] expected = pt.TealSimpleBlock( irPrefix + [ pt.TealOp(dynamicIndex, pt.Op.int, 2), pt.TealOp( dynamicElementExpr, dynamicArrayOp, *immediateArgs ), ] ) expected.addIncoming() expected = pt.TealBlock.NormalizeBlocks(expected) version = max(dynamicArrayOp.min_version, field.min_version) actual, _ = dynamicElementExpr.__teal__( pt.CompileOptions(version=version) ) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) assert ( actual == expected ), "{}: dynamic array field {} does not match expected".format( dynamicArrayOp, field ) if version > 2: with pytest.raises(pt.TealInputError): dynamicElementExpr.__teal__( pt.CompileOptions(version=version - 1) ) continue if field in arrayFieldToLengthField.values(): # ignore length fields since they are checked with their arrays continue if field == pt.TxnField.first_valid_time: # ignore first_valid_time since it is not exposed on pt.TxnObject yet continue expr = fieldToMethod[field](txnObject) immediateArgs = immediateArgsPrefix + [field.arg_name] expected = pt.TealSimpleBlock( irPrefix + [pt.TealOp(expr, op, *immediateArgs)] ) expected.addIncoming() expected = pt.TealBlock.NormalizeBlocks(expected) version = max(op.min_version, field.min_version) actual, _ = expr.__teal__(pt.CompileOptions(version=version)) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) assert actual == expected, "{}: field {} does not match expected".format( op, field ) if version > 2: with pytest.raises(pt.TealInputError): expr.__teal__(pt.CompileOptions(version=version - 1))
import pytest import pyteal as pt avm2Options = pt.CompileOptions(version=2) avm3Options = pt.CompileOptions(version=3) avm4Options = pt.CompileOptions(version=4) avm5Options = pt.CompileOptions(version=5) def test_add(): args = [pt.Int(2), pt.Int(3)] expr = pt.Add(args[0], args[1]) assert expr.type_of() == pt.TealType.uint64 expected = pt.TealSimpleBlock([ pt.TealOp(args[0], pt.Op.int, 2), pt.TealOp(args[1], pt.Op.int, 3), pt.TealOp(expr, pt.Op.add), ]) actual, _ = expr.__teal__(avm2Options) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) assert actual == expected def test_add_overload(): args = [pt.Int(2), pt.Int(3), pt.Int(4)] expr = args[0] + args[1] + args[2]
import pytest import pyteal as pt teal6Options = pt.CompileOptions(version=6) teal7Options = pt.CompileOptions(version=7) def test_vrf_verify_algorand(): args = [pt.Bytes("a"), pt.Bytes("b"), pt.Bytes("c")] expr = pt.VrfVerify.algorand(*args) assert expr.type_of() == pt.TealType.none expected = pt.TealSimpleBlock([ pt.TealOp(args[0], pt.Op.byte, '"a"'), pt.TealOp(args[1], pt.Op.byte, '"b"'), pt.TealOp(args[2], pt.Op.byte, '"c"'), pt.TealOp(expr, pt.Op.vrf_verify, "VrfAlgorand"), pt.TealOp(expr.output_slots[1], pt.Op.store, expr.output_slots[1]), pt.TealOp(expr.output_slots[0], pt.Op.store, expr.output_slots[0]), ]) actual, _ = expr.__teal__(teal7Options) actual.addIncoming() actual = pt.TealBlock.NormalizeBlocks(actual) with pt.TealComponent.Context.ignoreExprEquality(): assert actual == expected with pytest.raises(pt.TealInputError): expr.__teal__(teal6Options)