Beispiel #1
0
def test_replace_constant_no(source):
    unmodified_ast = sri_ast.parse_to_ast(source)
    folded_ast = sri_ast.parse_to_ast(source)

    folding.replace_constant(folded_ast, "FOO", sri_ast.Int(value=31337), True)

    assert sri_ast.compare_nodes(unmodified_ast, folded_ast)
Beispiel #2
0
def test_replace_subscripts_nested():
    test_ast = sri_ast.parse_to_ast("[[0, 1], [2, 3], [4, 5]][2][1]")
    expected_ast = sri_ast.parse_to_ast("5")

    folding.replace_subscripts(test_ast)

    assert sri_ast.compare_nodes(test_ast, expected_ast)
Beispiel #3
0
def test_replace_binop_simple():
    test_ast = sri_ast.parse_to_ast("1 + 2")
    expected_ast = sri_ast.parse_to_ast("3")

    folding.replace_literal_ops(test_ast)

    assert sri_ast.compare_nodes(test_ast, expected_ast)
Beispiel #4
0
def test_replace_builtin_constant_no(source):
    unmodified_ast = sri_ast.parse_to_ast(source)
    folded_ast = sri_ast.parse_to_ast(source)

    folding.replace_builtin_constants(folded_ast)

    assert sri_ast.compare_nodes(unmodified_ast, folded_ast)
Beispiel #5
0
def test_replace_builtins(source, original, result):
    original_ast = sri_ast.parse_to_ast(source.format(original))
    target_ast = sri_ast.parse_to_ast(source.format(result))

    folding.replace_builtin_functions(original_ast)

    assert sri_ast.compare_nodes(original_ast, target_ast)
Beispiel #6
0
def test_replace_binop_nested():
    test_ast = sri_ast.parse_to_ast("((6 + (2**4)) * 4) / 2")
    expected_ast = sri_ast.parse_to_ast("44")

    folding.replace_literal_ops(test_ast)

    assert sri_ast.compare_nodes(test_ast, expected_ast)
Beispiel #7
0
def test_replace_subscripts_simple():
    test_ast = sri_ast.parse_to_ast("[foo, bar, baz][1]")
    expected_ast = sri_ast.parse_to_ast("bar")

    folding.replace_subscripts(test_ast)

    assert sri_ast.compare_nodes(test_ast, expected_ast)
Beispiel #8
0
def test_integration():
    test_ast = sri_ast.parse_to_ast("[1+2, 6+7][8-8]")
    expected_ast = sri_ast.parse_to_ast("3")

    folding.fold(test_ast)

    assert sri_ast.compare_nodes(test_ast, expected_ast)
Beispiel #9
0
def test_node_does_not_exist():
    test_tree = sri_ast.parse_to_ast("foo = 42")
    old_node = test_tree.body[0].target

    new_node = sri_ast.parse_to_ast("42").body[0].value

    with pytest.raises(CompilerPanic):
        test_tree.replace_in_tree(new_node, old_node)
Beispiel #10
0
def test_replace_literal_ops():
    test_ast = sri_ast.parse_to_ast(
        "[not True, True and False, True or False]")
    expected_ast = sri_ast.parse_to_ast("[False, False, True]")

    folding.replace_literal_ops(test_ast)

    assert sri_ast.compare_nodes(test_ast, expected_ast)
Beispiel #11
0
def test_replace_userdefined_constant_no(source):
    source = f"FOO: constant(int128) = 42\n{source}"

    unmodified_ast = sri_ast.parse_to_ast(source)
    folded_ast = sri_ast.parse_to_ast(source)

    folding.replace_user_defined_constants(folded_ast)

    assert sri_ast.compare_nodes(unmodified_ast, folded_ast)
Beispiel #12
0
def test_simple_replacement():
    test_tree = sri_ast.parse_to_ast("foo = 42")
    expected_tree = sri_ast.parse_to_ast("bar = 42")

    old_node = test_tree.body[0].target
    new_node = sri_ast.parse_to_ast("bar").body[0].value

    test_tree.replace_in_tree(old_node, new_node)

    assert sri_ast.compare_nodes(test_tree, expected_tree)
Beispiel #13
0
def test_cannot_replace_twice():
    test_tree = sri_ast.parse_to_ast("foo = 42")
    old_node = test_tree.body[0].target

    new_node = sri_ast.parse_to_ast("42").body[0].value

    test_tree.replace_in_tree(old_node, new_node)

    with pytest.raises(CompilerPanic):
        test_tree.replace_in_tree(old_node, new_node)
Beispiel #14
0
def test_list_replacement_similar_nodes():
    test_tree = sri_ast.parse_to_ast("foo = [1, 1, 1, 1, 1]")
    expected_tree = sri_ast.parse_to_ast("foo = [1, 1, 31337, 1, 1]")

    old_node = test_tree.body[0].value.elts[2]
    new_node = sri_ast.parse_to_ast("31337").body[0].value

    test_tree.replace_in_tree(old_node, new_node)

    assert sri_ast.compare_nodes(test_tree, expected_tree)
Beispiel #15
0
def test_assumptions():
    # ASTs generated seperately from the same source should compare equal
    test_tree = sri_ast.parse_to_ast("foo = 42")
    expected_tree = sri_ast.parse_to_ast("foo = 42")
    assert sri_ast.compare_nodes(test_tree, expected_tree)

    # ASTs generated seperately with different source should compare not-equal
    test_tree = sri_ast.parse_to_ast("foo = 42")
    expected_tree = sri_ast.parse_to_ast("bar = 666")
    assert not sri_ast.compare_nodes(test_tree, expected_tree)
Beispiel #16
0
def test_params():
    code = """
@public
def foo(bar: int128, baz: uint256, potato: bytes32):
    '''
    @param bar a number
    @param baz also a number
    @dev we didn't document potato, but that's ok
    '''
    pass
    """

    srilang_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    _, devdoc = parse_natspec(srilang_ast, global_ctx)

    assert devdoc == {
        "methods": {
            "foo(int128,uint256,bytes32)": {
                "details": "we didn't document potato, but that's ok",
                "params": {
                    "bar": "a number",
                    "baz": "also a number"
                },
            }
        }
    }
Beispiel #17
0
def test_returns():
    code = """
@public
def foo(bar: int128, baz: uint256) -> (int128, uint256):
    '''
    @return value of bar
    @return value of baz
    '''
    return bar, baz
    """

    srilang_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    _, devdoc = parse_natspec(srilang_ast, global_ctx)

    assert devdoc == {
        "methods": {
            "foo(int128,uint256)": {
                "returns": {
                    "_0": "value of bar",
                    "_1": "value of baz"
                }
            }
        }
    }
Beispiel #18
0
def test_documentation_example_output():
    srilang_ast = parse_to_ast(test_code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    userdoc, devdoc = parse_natspec(srilang_ast, global_ctx)

    assert userdoc == expected_userdoc
    assert devdoc == expected_devdoc
Beispiel #19
0
def test_compare_different_node_clases():
    srilang_ast = sri_ast.parse_to_ast("foo = 42")
    left = srilang_ast.body[0].target
    right = srilang_ast.body[0].value

    assert left != right
    assert not sri_ast.compare_nodes(left, right)
Beispiel #20
0
def test_compare_complex_nodes_same_value():
    srilang_ast = sri_ast.parse_to_ast(
        "[{'foo':'bar', 43:[1,2,3]}, {'foo':'bar', 43:[1,2,3]}]")
    left, right = srilang_ast.body[0].value.elts

    assert left != right
    assert sri_ast.compare_nodes(left, right)
Beispiel #21
0
def test_no_tags_implies_notice():
    code = """
'''
Because there is no tag, this docstring is handled as a notice.
'''
@public
def foo():
    '''
    This one too!
    '''
    pass
    """

    srilang_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    userdoc, devdoc = parse_natspec(srilang_ast, global_ctx)

    assert userdoc == {
        "methods": {
            "foo()": {
                "notice": "This one too!"
            }
        },
        "notice":
        "Because there is no tag, this docstring is handled as a notice.",
    }
    assert not devdoc
Beispiel #22
0
def test_nested(get_contract, assert_tx_failed, values, ops):
    variables = "abcdefghij"
    input_value = ",".join(f"{i}: decimal" for i in variables[:len(values)])
    return_value = " ".join(f"{a} {b}"
                            for a, b in zip(variables[:len(values)], ops))
    return_value = return_value.rsplit(maxsplit=1)[0]
    source = f"""
@public
def foo({input_value}) -> decimal:
    return {return_value}
    """
    contract = get_contract(source)

    literal_op = " ".join(f"{a} {b}" for a, b in zip(values, ops))
    literal_op = literal_op.rsplit(maxsplit=1)[0]
    srilang_ast = sri_ast.parse_to_ast(literal_op)
    try:
        sri_ast.folding.replace_literal_ops(srilang_ast)
        expected = srilang_ast.body[0].value.value
        is_valid = -2**127 <= expected < 2**127
    except ZeroDivisionException:
        # for division/modulus by 0, expect the contract call to revert
        is_valid = False

    if is_valid:
        assert contract.foo(*values) == expected
    else:
        assert_tx_failed(lambda: contract.foo(*values))
Beispiel #23
0
def test_binop_pow():
    # raises because srilang does not support decimal exponentiation
    srilang_ast = sri_ast.parse_to_ast(f"3.1337 ** 4.2")
    old_node = srilang_ast.body[0].value

    with pytest.raises(TypeMismatch):
        old_node.evaluate()
Beispiel #24
0
def test_whitespace():
    code = """
'''
        @dev

  Whitespace    gets  cleaned
    up,
            people can use


         awful formatting.


We don't mind!

@author Mr No-linter
                '''
"""
    srilang_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    _, devdoc = parse_natspec(srilang_ast, global_ctx)

    assert devdoc == {
        "author":
        "Mr No-linter",
        "details":
        "Whitespace gets cleaned up, people can use awful formatting. We don't mind!",
    }
Beispiel #25
0
def test_order():
    node = sri_ast.parse_to_ast(
        "[(1 + (2 - 3)) / 4 ** 5, 6 - (7 / -(8 % 9)), 0]")
    node = node.body[0].value
    values = [i.value for i in node.get_descendants(sri_ast.Int)]

    assert values == [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
Beispiel #26
0
def test_parents_children():
    test_tree = sri_ast.parse_to_ast("foo = 42")

    old_node = test_tree.body[0].target
    parent = old_node.get_ancestor()

    new_node = sri_ast.parse_to_ast("bar").body[0].value
    test_tree.replace_in_tree(old_node, new_node)

    assert old_node.get_ancestor() == new_node.get_ancestor()

    assert old_node not in parent.get_children()
    assert new_node in parent.get_children()

    assert old_node not in test_tree.get_descendants()
    assert new_node in test_tree.get_descendants()
Beispiel #27
0
def test_binop_nested(get_contract, assert_tx_failed, values, ops):

    variables = "abcdefghij"
    input_value = ",".join(f"{i}: int128" for i in variables[:len(values)])
    return_value = " ".join(f"{a} {b}"
                            for a, b in zip(variables[:len(values)], ops))
    return_value = return_value.rsplit(maxsplit=1)[0]

    source = f"""
@public
def foo({input_value}) -> int128:
    return {return_value}
    """
    contract = get_contract(source)

    literal_op = " ".join(f"{a} {b}" for a, b in zip(values, ops))
    literal_op = literal_op.rsplit(maxsplit=1)[0]

    srilang_ast = sri_ast.parse_to_ast(literal_op)

    try:
        sri_ast.folding.replace_literal_ops(srilang_ast)
        expected = srilang_ast.body[0].value.value
        is_valid = True
    except ZeroDivisionException:
        is_valid = False

    if is_valid:
        assert contract.foo(*values) == expected
    else:
        assert_tx_failed(lambda: contract.foo(*values))
Beispiel #28
0
def test_basic_grammar(lark_grammar):
    code = """
    a: uint256
    b: uint128
    """
    code_func = """
    @public
    def one_two_three() -> uint256:
        return 123123123
    """

    assert lark_grammar.parse(textwrap.dedent(code) + "\n")
    assert parse_to_ast(textwrap.dedent(code))

    assert lark_grammar.parse(textwrap.dedent(code_func) + "\n")
    assert parse_to_ast(textwrap.dedent(code_func))
Beispiel #29
0
def test_order_reversed():
    node = sri_ast.parse_to_ast(
        "[(1 + (2 - 3)) / 4 ** 5, 6 - (7 / -(8 % 9)), 0]")
    node = node.body[0].value
    values = [i.value for i in node.get_descendants(sri_ast.Int, reverse=True)]

    assert values == [0, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Beispiel #30
0
def test_type_filter():
    srilang_ast = sri_ast.parse_to_ast(
        "[1, (2, (3, (4, 5.0), 'six')), 7, 0x08]")
    descendants = srilang_ast.get_descendants(sri_ast.Int)

    assert len(descendants) == 5
    assert not next(
        (i for i in descendants if not isinstance(i, sri_ast.Int)), False)