Exemple #1
0
def test_empty_param(bad_docstring):
    code = f"""
@public
def foo(a: int128):
    '''{bad_docstring}'''
    pass
    """
    srilang_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    with pytest.raises(NatSpecSyntaxException,
                       match="No description given for parameter 'a'"):
        parse_natspec(srilang_ast, global_ctx)
Exemple #2
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
    """

    srilang_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    with pytest.raises(NatSpecSyntaxException,
                       match="Method does not return any values"):
        parse_natspec(srilang_ast, global_ctx)
Exemple #3
0
def test_invalid_field():
    code = """
@public
def foo():
    '''@title function level docstrings cannot have titles'''
    pass
    """

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

    srilang_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    with pytest.raises(NatSpecSyntaxException,
                       match="Method has no parameter 'hotdog'"):
        parse_natspec(srilang_ast, global_ctx)
Exemple #5
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!",
    }
Exemple #6
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
Exemple #7
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
Exemple #8
0
def test_duplicate_param():
    code = """
@public
def foo(bar: int128, baz: uint256):
    '''
    @param bar a number
    @param bar also a number
    '''
    pass
    """

    srilang_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    with pytest.raises(NatSpecSyntaxException,
                       match="Parameter 'bar' documented more than once"):
        parse_natspec(srilang_ast, global_ctx)
Exemple #9
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
    """

    srilang_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    with pytest.raises(NatSpecSyntaxException,
                       match="Duplicate NatSpec field '@notice'"):
        parse_natspec(srilang_ast, global_ctx)
Exemple #10
0
def test_unknown_field():
    code = """
@public
def foo():
    '''
    @notice this is ok
    @thing this is bad
    '''
    pass
    """

    srilang_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    with pytest.raises(NatSpecSyntaxException,
                       match="Unknown NatSpec field '@thing'"):
        parse_natspec(srilang_ast, global_ctx)
Exemple #11
0
def test_partial_natspec():
    code = """
@public
def foo():
    '''
    Regular comments preceeding natspec is not allowed
    @notice this is natspec
    '''
    pass
    """

    srilang_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    with pytest.raises(NatSpecSyntaxException,
                       match="NatSpec docstring opens with untagged comment"):
        parse_natspec(srilang_ast, global_ctx)
Exemple #12
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"
                }
            }
        }
    }
Exemple #13
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"
                },
            }
        }
    }
Exemple #14
0
def test_too_many_returns_single_return_type():
    code = """
@public
def foo() -> int128:
    '''
    @return int128
    @return this should fail
    '''
    return 1
    """

    srilang_ast = parse_to_ast(code)
    global_ctx = GlobalContext.get_global_context(srilang_ast)
    with pytest.raises(
            NatSpecSyntaxException,
            match="Number of documented return values exceeds actual number",
    ):
        parse_natspec(srilang_ast, global_ctx)
Exemple #15
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
    """

    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)": {
            "details": "I will be parsed."
        }
    }
Exemple #16
0
def build_userdoc(compiler_data: CompilerData) -> dict:
    userdoc, devdoc = parse_natspec(compiler_data.srilang_module,
                                    compiler_data.global_ctx)
    return userdoc