Example #1
0
def test_replace_builtins(source, original, result):
    original_ast = vy_ast.parse_to_ast(source.format(original))
    target_ast = vy_ast.parse_to_ast(source.format(result))

    folding.replace_builtin_functions(original_ast)

    assert vy_ast.compare_nodes(original_ast, target_ast)
Example #2
0
def test_replace_literal_ops():
    test_ast = vy_ast.parse_to_ast("[not True, True and False, True or False]")
    expected_ast = vy_ast.parse_to_ast("[False, False, True]")

    folding.replace_literal_ops(test_ast)

    assert vy_ast.compare_nodes(test_ast, expected_ast)
Example #3
0
def test_replace_subscripts_simple():
    test_ast = vy_ast.parse_to_ast("[foo, bar, baz][1]")
    expected_ast = vy_ast.parse_to_ast("bar")

    folding.replace_subscripts(test_ast)

    assert vy_ast.compare_nodes(test_ast, expected_ast)
Example #4
0
def test_replace_binop_nested():
    test_ast = vy_ast.parse_to_ast("((6 + (2**4)) * 4) / 2")
    expected_ast = vy_ast.parse_to_ast("44")

    folding.replace_literal_ops(test_ast)

    assert vy_ast.compare_nodes(test_ast, expected_ast)
Example #5
0
def test_replace_constant_no(source):
    unmodified_ast = vy_ast.parse_to_ast(source)
    folded_ast = vy_ast.parse_to_ast(source)

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

    assert vy_ast.compare_nodes(unmodified_ast, folded_ast)
Example #6
0
def test_replace_builtin_constant_no(source):
    unmodified_ast = vy_ast.parse_to_ast(source)
    folded_ast = vy_ast.parse_to_ast(source)

    folding.replace_builtin_constants(folded_ast)

    assert vy_ast.compare_nodes(unmodified_ast, folded_ast)
Example #7
0
def test_replace_binop_simple():
    test_ast = vy_ast.parse_to_ast("1 + 2")
    expected_ast = vy_ast.parse_to_ast("3")

    folding.replace_literal_ops(test_ast)

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

    folding.fold(test_ast)

    assert vy_ast.compare_nodes(test_ast, expected_ast)
Example #9
0
def test_replace_subscripts_nested():
    test_ast = vy_ast.parse_to_ast("[[0, 1], [2, 3], [4, 5]][2][1]")
    expected_ast = vy_ast.parse_to_ast("5")

    folding.replace_subscripts(test_ast)

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

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

    with pytest.raises(CompilerPanic):
        test_tree.replace_in_tree(new_node, old_node)
Example #11
0
def test_replace_userdefined_constant_no(source):
    source = f"FOO: constant(int128) = 42\n{source}"

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

    folding.replace_user_defined_constants(folded_ast)

    assert vy_ast.compare_nodes(unmodified_ast, folded_ast)
Example #12
0
def test_assumptions():
    # ASTs generated seperately from the same source should compare equal
    test_tree = vy_ast.parse_to_ast("foo = 42")
    expected_tree = vy_ast.parse_to_ast("foo = 42")
    assert vy_ast.compare_nodes(test_tree, expected_tree)

    # ASTs generated seperately with different source should compare not-equal
    test_tree = vy_ast.parse_to_ast("foo = 42")
    expected_tree = vy_ast.parse_to_ast("bar = 666")
    assert not vy_ast.compare_nodes(test_tree, expected_tree)
Example #13
0
def test_list_replacement_similar_nodes():
    test_tree = vy_ast.parse_to_ast("foo = [1, 1, 1, 1, 1]")
    expected_tree = vy_ast.parse_to_ast("foo = [1, 1, 31337, 1, 1]")

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

    test_tree.replace_in_tree(old_node, new_node)

    assert vy_ast.compare_nodes(test_tree, expected_tree)
Example #14
0
def test_simple_replacement():
    test_tree = vy_ast.parse_to_ast("foo = 42")
    expected_tree = vy_ast.parse_to_ast("bar = 42")

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

    test_tree.replace_in_tree(old_node, new_node)

    assert vy_ast.compare_nodes(test_tree, expected_tree)
Example #15
0
def test_cannot_replace_twice():
    test_tree = vy_ast.parse_to_ast("foo = 42")
    old_node = test_tree.body[0].target

    new_node = vy_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)
Example #16
0
def test_replace_userdefined_attribute(source):
    preamble = f"ADDR: constant(address) = {dummy_address}"
    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)
Example #17
0
def test_parents_children():
    test_tree = vy_ast.parse_to_ast("foo = 42")

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

    new_node = vy_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()
Example #18
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]
    vyper_ast = vy_ast.parse_to_ast(literal_op)
    try:
        vy_ast.folding.replace_literal_ops(vyper_ast)
        expected = vyper_ast.body[0].value.value
        is_valid = True
    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))
Example #19
0
def test_binop_pow():
    # raises because Vyper does not support decimal exponentiation
    vyper_ast = vy_ast.parse_to_ast(f"3.1337 ** 4.2")
    old_node = vyper_ast.body[0].value

    with pytest.raises(TypeMismatch):
        old_node.evaluate()
Example #20
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
    """

    vyper_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    userdoc, devdoc = parse_natspec(vyper_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
Example #21
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
    """

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

    assert devdoc == {
        "methods": {
            "foo(int128,uint256)": {
                "returns": {
                    "_0": "value of bar",
                    "_1": "value of baz"
                }
            }
        }
    }
Example #22
0
def extract_sigs(sig_code, interface_name=None):
    if sig_code["type"] == "vyper":
        interface_ast = [
            i for i in vy_ast.parse_to_ast(sig_code["code"],
                                           contract_name=interface_name)
            # all the nodes visited by ModuleNodeVisitor.
            if isinstance(
                i,
                (
                    vy_ast.FunctionDef,
                    vy_ast.EnumDef,
                    vy_ast.EventDef,
                    vy_ast.StructDef,
                    vy_ast.InterfaceDef,
                    # parsing import statements at this stage
                    # causes issues with recursive imports
                    # vy_ast.Import,
                    # vy_ast.ImportFrom,
                ),
            ) or
            (isinstance(i, vy_ast.AnnAssign) and i.target.id != "implements")
        ]
        global_ctx = GlobalContext.get_global_context(interface_ast)
        return _get_external_signatures(global_ctx)
    elif sig_code["type"] == "json":
        return mk_full_signature_from_json(sig_code["code"])
    else:
        raise Exception((
            f"Unknown interface signature type '{sig_code['type']}' supplied. "
            "'vyper' & 'json' are supported"))
Example #23
0
 def _build_node(source):
     # docstring ensures string nodes are properly generated, not turned into docstrings
     source = f"""'I am a docstring.'\n{source}"""
     ast = vy_ast.parse_to_ast(source).body[0]
     if isinstance(ast, vy_ast.Expr):
         ast = ast.value
     return ast
Example #24
0
def test_type_filter():
    vyper_ast = vy_ast.parse_to_ast("[1, (2, (3, (4, 5.0), 'six')), 7, 0x08]")
    descendants = vyper_ast.get_descendants(vy_ast.Int)

    assert len(descendants) == 5
    assert not next(
        (i for i in descendants if not isinstance(i, vy_ast.Int)), False)
Example #25
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
    """

    vyper_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    _, devdoc = parse_natspec(vyper_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"
                },
            }
        }
    }
Example #26
0
def test_order():
    node = vy_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(vy_ast.Int)]

    assert values == [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
Example #27
0
def test_documentation_example_output():
    vyper_ast = parse_to_ast(test_code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    userdoc, devdoc = parse_natspec(vyper_ast, global_ctx)

    assert userdoc == expected_userdoc
    assert devdoc == expected_devdoc
Example #28
0
def test_order_reversed():
    node = vy_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(vy_ast.Int, reverse=True)]

    assert values == [0, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Example #29
0
def test_whitespace():
    code = """
'''
        @dev

  Whitespace    gets  cleaned
    up,
            people can use


         awful formatting.


We don't mind!

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

    assert devdoc == {
        "author":
        "Mr No-linter",
        "details":
        "Whitespace gets cleaned up, people can use awful formatting. We don't mind!",
    }
Example #30
0
def test_compare_different_node_clases():
    vyper_ast = vy_ast.parse_to_ast("foo = 42")
    left = vyper_ast.body[0].target
    right = vyper_ast.body[0].value

    assert left != right
    assert not vy_ast.compare_nodes(left, right)