예제 #1
0
def test_empty_param(bad_docstring):
    code = f"""
@public
def foo(a: int128):
    '''{bad_docstring}'''
    pass
    """
    vyper_ast = parse_to_ast(code)
    with pytest.raises(NatSpecSyntaxException, match="No description given for parameter 'a'"):
        parse_natspec(vyper_ast)
예제 #2
0
def test_empty_field(bad_docstring):
    code = f"""
@public
def foo():
    '''{bad_docstring}'''
    pass
    """
    vyper_ast = parse_to_ast(code)
    with pytest.raises(NatSpecSyntaxException, match="No description given for tag '@notice'"):
        parse_natspec(vyper_ast)
예제 #3
0
def test_invalid_field():
    code = """
@public
def foo():
    '''@title function level docstrings cannot have titles'''
    pass
    """

    vyper_ast = parse_to_ast(code)
    with pytest.raises(NatSpecSyntaxException, match="'@title' is not a valid field"):
        parse_natspec(vyper_ast)
예제 #4
0
def test_unknown_param():
    code = """
@public
def foo(bar: int128, baz: uint256):
    '''@param hotdog not a number'''
    pass
    """

    vyper_ast = parse_to_ast(code)
    with pytest.raises(NatSpecSyntaxException, match="Method has no parameter 'hotdog'"):
        parse_natspec(vyper_ast)
예제 #5
0
def test_too_many_returns_no_return_type():
    code = """
@public
def foo():
    '''@return should fail, the function does not include a return value'''
    pass
    """

    vyper_ast = parse_to_ast(code)
    with pytest.raises(NatSpecSyntaxException, match="Method does not return any values"):
        parse_natspec(vyper_ast)
예제 #6
0
def test_empty_param(bad_docstring):
    code = f"""
@external
def foo(a: int128):
    '''{bad_docstring}'''
    pass
    """
    vyper_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    with pytest.raises(NatSpecSyntaxException, match="No description given for parameter 'a'"):
        parse_natspec(vyper_ast, global_ctx)
예제 #7
0
def test_too_many_returns_no_return_type():
    code = """
@external
def foo():
    '''@return should fail, the function does not include a return value'''
    pass
    """

    vyper_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    with pytest.raises(NatSpecSyntaxException, match="Method does not return any values"):
        parse_natspec(vyper_ast, global_ctx)
예제 #8
0
def test_unknown_param():
    code = """
@external
def foo(bar: int128, baz: uint256):
    '''@param hotdog not a number'''
    pass
    """

    vyper_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    with pytest.raises(NatSpecSyntaxException, match="Method has no parameter 'hotdog'"):
        parse_natspec(vyper_ast, global_ctx)
예제 #9
0
def test_invalid_field(field):
    code = f"""
@external
def foo():
    '''@{field} function level docstrings cannot have titles'''
    pass
    """

    vyper_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    with pytest.raises(NatSpecSyntaxException, match=f"'@{field}' is not a valid field"):
        parse_natspec(vyper_ast, global_ctx)
예제 #10
0
def test_unknown_field():
    code = """
@public
def foo():
    '''
    @notice this is ok
    @thing this is bad
    '''
    pass
    """

    vyper_ast = parse_to_ast(code)
    with pytest.raises(NatSpecSyntaxException, match="Unknown NatSpec field '@thing'"):
        parse_natspec(vyper_ast)
예제 #11
0
def test_empty_fields(field):
    code = f"""
'''
@{field}
'''
@external
def foo():
    pass
    """

    vyper_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    with pytest.raises(NatSpecSyntaxException, match=f"No description given for tag '@{field}'"):
        parse_natspec(vyper_ast, global_ctx)
예제 #12
0
def test_duplicate_fields():
    code = """
@public
def foo():
    '''
    @notice It's fine to have one notice, but....
    @notice a second one, not so much
    '''
    pass
    """

    vyper_ast = parse_to_ast(code)
    with pytest.raises(NatSpecSyntaxException, match="Duplicate NatSpec field '@notice'"):
        parse_natspec(vyper_ast)
예제 #13
0
def test_unknown_field():
    code = """
@external
def foo():
    '''
    @notice this is ok
    @thing this is bad
    '''
    pass
    """

    vyper_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    with pytest.raises(NatSpecSyntaxException, match="Unknown NatSpec field '@thing'"):
        parse_natspec(vyper_ast, global_ctx)
예제 #14
0
def test_duplicate_param():
    code = """
@external
def foo(bar: int128, baz: uint256):
    '''
    @param bar a number
    @param bar also a number
    '''
    pass
    """

    vyper_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    with pytest.raises(NatSpecSyntaxException, match="Parameter 'bar' documented more than once"):
        parse_natspec(vyper_ast, global_ctx)
예제 #15
0
def test_duplicate_fields():
    code = """
@external
def foo():
    '''
    @notice It's fine to have one notice, but....
    @notice a second one, not so much
    '''
    pass
    """

    vyper_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    with pytest.raises(NatSpecSyntaxException, match="Duplicate NatSpec field '@notice'"):
        parse_natspec(vyper_ast, global_ctx)
예제 #16
0
def test_duplicate_param():
    code = """
@public
def foo(bar: int128, baz: uint256):
    '''
    @param bar a number
    @param bar also a number
    '''
    pass
    """

    vyper_ast = parse_to_ast(code)
    with pytest.raises(
        NatSpecSyntaxException, match="Parameter 'bar' documented more than once"
    ):
        parse_natspec(vyper_ast)
예제 #17
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!",
    }
예제 #18
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
예제 #19
0
def test_partial_natspec():
    code = """
@public
def foo():
    '''
    Regular comments preceeding natspec is not allowed
    @notice this is natspec
    '''
    pass
    """

    vyper_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    with pytest.raises(NatSpecSyntaxException,
                       match="NatSpec docstring opens with untagged comment"):
        parse_natspec(vyper_ast, global_ctx)
예제 #20
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
예제 #21
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"
                },
            }
        }
    }
예제 #22
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"
                }
            }
        }
    }
예제 #23
0
def test_too_many_returns_single_return_type():
    code = """
@public
def foo() -> int128:
    '''
    @return int128
    @return this should fail
    '''
    return 1
    """

    vyper_ast = parse_to_ast(code)
    with pytest.raises(
        NatSpecSyntaxException,
        match="Number of documented return values exceeds actual number",
    ):
        parse_natspec(vyper_ast)
예제 #24
0
def test_too_many_returns_tuple_return_type():
    code = """
@external
def foo() -> (int128,uint256):
    '''
    @return int128
    @return uint256
    @return this should fail
    '''
    return 1, 2
    """

    vyper_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(vyper_ast)
    with pytest.raises(
        NatSpecSyntaxException, match="Number of documented return values exceeds actual number",
    ):
        parse_natspec(vyper_ast, global_ctx)
예제 #25
0
def test_license(license):
    code = f"""
'''
@license {license}
'''
@external
def foo():
    pass
    """

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

    assert devdoc == {
        "license": license,
    }
예제 #26
0
def test_ignore_private_methods():
    code = """
@external
def foo(bar: int128, baz: uint256):
    '''@dev I will be parsed.'''
    pass

@internal
def notfoo(bar: int128, baz: uint256):
    '''@dev I will not be parsed.'''
    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)": {"details": "I will be parsed."}}
예제 #27
0
def test_ignore_private_methods():
    code = """
@public
def foo(bar: int128, baz: uint256):
    '''@dev I will be parsed.'''
    pass

@private
def notfoo(bar: int128, baz: uint256):
    '''@dev I will not be parsed.'''
    pass
    """

    vyper_ast = parse_to_ast(code)
    _, devdoc = parse_natspec(vyper_ast)

    assert devdoc["methods"] == {
        "foo(int128,uint256)": {"details": "I will be parsed."}
    }
예제 #28
0
def _mk_devdoc(code, contract_name, interface_codes, source_id):
    vyper_ast = parse_to_ast(code)
    userdoc, devdoc = parse_natspec(vyper_ast, interface_codes)
    return devdoc
예제 #29
0
def build_userdoc(compiler_data: CompilerData) -> dict:
    userdoc, devdoc = parse_natspec(compiler_data.vyper_module_folded)
    return userdoc
예제 #30
0
def test_documentation_example_output():
    vyper_ast = parse_to_ast(test_code)
    userdoc, devdoc = parse_natspec(vyper_ast)

    assert userdoc == expected_userdoc
    assert devdoc == expected_devdoc