ClickUp Operator
by noahvanhart
"""Tests for numpydoc-style docstring routines."""
import typing as T
import pytest
from docstring_parser.numpydoc import compose, parse
@pytest.mark.parametrize(
"source, expected",
[
("", None),
("\n", None),
("Short description", "Short description"),
("\nShort description\n", "Short description"),
("\n Short description\n", "Short description"),
],
)
def test_short_description(source: str, expected: str) -> None:
"""Test parsing short description."""
docstring = parse(source)
assert docstring.short_description == expected
assert docstring.long_description is None
assert not docstring.meta
@pytest.mark.parametrize(
"source, expected_short_desc, expected_long_desc, expected_blank",
[
(
"Short description\n\nLong description",
"Short description",
"Long description",
True,
),
(
"""
Short description
Long description
""",
"Short description",
"Long description",
True,
),
(
"""
Short description
Long description
Second line
""",
"Short description",
"Long description\nSecond line",
True,
),
(
"Short description\nLong description",
"Short description",
"Long description",
False,
),
(
"""
Short description
Long description
""",
"Short description",
"Long description",
False,
),
(
"\nShort description\nLong description\n",
"Short description",
"Long description",
False,
),
(
"""
Short description
Long description
Second line
""",
"Short description",
"Long description\nSecond line",
False,
),
],
)
def test_long_description(
source: str,
expected_short_desc: str,
expected_long_desc: str,
expected_blank: bool,
) -> None:
"""Test parsing long description."""
docstring = parse(source)
assert docstring.short_description == expected_short_desc
assert docstring.long_description == expected_long_desc
assert docstring.blank_after_short_description == expected_blank
assert not docstring.meta
@pytest.mark.parametrize(
"source, expected_short_desc, expected_long_desc, "
"expected_blank_short_desc, expected_blank_long_desc",
[
(
"""
Short description
Parameters
----------
asd
""",
"Short description",
None,
False,
False,
),
(
"""
Short description
Long description
Parameters
----------
asd
""",
"Short description",
"Long description",
False,
False,
),
(
"""
Short description
First line
Second line
Parameters
----------
asd
""",
"Short description",
"First line\n Second line",
False,
False,
),
(
"""
Short description
First line
Second line
Parameters
----------
asd
""",
"Short description",
"First line\n Second line",
True,
False,
),
(
"""
Short description
First line
Second line
Parameters
----------
asd
""",
"Short description",
"First line\n Second line",
True,
True,
),
(
"""
Parameters
----------
asd
""",
None,
None,
False,
False,
),
],
)
def test_meta_newlines(
source: str,
expected_short_desc: T.Optional[str],
expected_long_desc: T.Optional[str],
expected_blank_short_desc: bool,
expected_blank_long_desc: bool,
) -> None:
"""Test parsing newlines around description sections."""
docstring = parse(source)
assert docstring.short_description == expected_short_desc
assert docstring.long_description == expected_long_desc
assert docstring.blank_after_short_description == expected_blank_short_desc
assert docstring.blank_after_long_description == expected_blank_long_desc
assert len(docstring.meta) == 1
def test_meta_with_multiline_description() -> None:
"""Test parsing multiline meta documentation."""
docstring = parse(
"""
Short description
Parameters
----------
spam
asd
1
2
3
"""
)
assert docstring.short_description == "Short description"
assert len(docstring.meta) == 1
assert docstring.meta[0].args == ["param", "spam"]
assert docstring.meta[0].arg_name == "spam"
assert docstring.meta[0].description == "asd\n1\n 2\n3"
@pytest.mark.parametrize(
"source, expected_is_optional, expected_type_name, expected_default",
[
(
"""
Parameters
----------
arg1 : int
The first arg
""",
False,
"int",
None,
),
(
"""
Parameters
----------
arg2 : str
The second arg
""",
False,
"str",
None,
),
(
"""
Parameters
----------
arg3 : float, optional
The third arg. Default is 1.0.
""",
True,
"float",
"1.0",
),
(
"""
Parameters
----------
arg4 : Optional[Dict[str, Any]], optional
The fourth arg. Defaults to None
""",
True,
"Optional[Dict[str, Any]]",
"None",
),
(
"""
Parameters
----------
arg5 : str, optional
The fifth arg. Default: DEFAULT_ARGS
""",
True,
"str",
"DEFAULT_ARGS",
),
(
"""
Parameters
----------
parameter_without_default : int
The parameter_without_default is required.
""",
False,
"int",
None,
),
],
)
def test_default_args(
source: str,
expected_is_optional: bool,
expected_type_name: T.Optional[str],
expected_default: T.Optional[str],
) -> None:
"""Test parsing default arguments."""
docstring = parse(source)
assert docstring is not None
assert len(docstring.params) == 1
arg1 = docstring.params[0]
assert arg1.is_optional == expected_is_optional
assert arg1.type_name == expected_type_name
assert arg1.default == expected_default
def test_multiple_meta() -> None:
"""Test parsing multiple meta."""
docstring = parse(
"""
Short description
Parameters
----------
spam
asd
1
2
3
Raises
------
bla
herp
yay
derp
"""
)
assert docstring.short_description == "Short description"
assert len(docstring.meta) == 3
assert docstring.meta[0].args == ["param", "spam"]
assert docstring.meta[0].arg_name == "spam"
assert docstring.meta[0].description == "asd\n1\n 2\n3"
assert docstring.meta[1].args == ["raises", "bla"]
assert docstring.meta[1].type_name == "bla"
assert docstring.meta[1].description == "herp"
assert docstring.meta[2].args == ["raises", "yay"]
assert docstring.meta[2].type_name == "yay"
assert docstring.meta[2].description == "derp"
def test_params() -> None:
"""Test parsing params."""
docstring = parse("Short description")
assert len(docstring.params) == 0
docstring = parse(
"""
Short description
Parameters
----------
name
description 1
priority : int
description 2
sender : str, optional
description 3
ratio : Optional[float], optional
description 4
"""
)
assert len(docstring.params) == 4
assert docstring.params[0].arg_name == "name"
assert docstring.params[0].type_name is None
assert docstring.params[0].description == "description 1"
assert not docstring.params[0].is_optional
assert docstring.params[1].arg_name == "priority"
assert docstring.params[1].type_name == "int"
assert docstring.params[1].description == "description 2"
assert not docstring.params[1].is_optional
assert docstring.params[2].arg_name == "sender"
assert docstring.params[2].type_name == "str"
assert docstring.params[2].description == "description 3"
assert docstring.params[2].is_optional
assert docstring.params[3].arg_name == "ratio"
assert docstring.params[3].type_name == "Optional[float]"
assert docstring.params[3].description == "description 4"
assert docstring.params[3].is_optional
docstring = parse(
"""
Short description
Parameters
----------
name
description 1
with multi-line text
priority : int
description 2
"""
)
assert len(docstring.params) == 2
assert docstring.params[0].arg_name == "name"
assert docstring.params[0].type_name is None
assert docstring.params[0].description == (
"description 1\nwith multi-line text"
)
assert docstring.params[1].arg_name == "priority"
assert docstring.params[1].type_name == "int"
assert docstring.params[1].description == "description 2"
def test_attributes() -> None:
"""Test parsing attributes."""
docstring = parse("Short description")
assert len(docstring.params) == 0
docstring = parse(
"""
Short description
Attributes
----------
name
description 1
priority : int
description 2
sender : str, optional
description 3
ratio : Optional[float], optional
description 4
"""
)
assert len(docstring.params) == 4
assert docstring.params[0].arg_name == "name"
assert docstring.params[0].type_name is None
assert docstring.params[0].description == "description 1"
assert not docstring.params[0].is_optional
assert docstring.params[1].arg_name == "priority"
assert docstring.params[1].type_name == "int"
assert docstring.params[1].description == "description 2"
assert not docstring.params[1].is_optional
assert docstring.params[2].arg_name == "sender"
assert docstring.params[2].type_name == "str"
assert docstring.params[2].description == "description 3"
assert docstring.params[2].is_optional
assert docstring.params[3].arg_name == "ratio"
assert docstring.params[3].type_name == "Optional[float]"
assert docstring.params[3].description == "description 4"
assert docstring.params[3].is_optional
docstring = parse(
"""
Short description
Attributes
----------
name
description 1
with multi-line text
priority : int
description 2
"""
)
assert len(docstring.params) == 2
assert docstring.params[0].arg_name == "name"
assert docstring.params[0].type_name is None
assert docstring.params[0].description == (
"description 1\nwith multi-line text"
)
assert docstring.params[1].arg_name == "priority"
assert docstring.params[1].type_name == "int"
assert docstring.params[1].description == "description 2"
def test_other_params() -> None:
"""Test parsing other parameters."""
docstring = parse(
"""
Short description
Other Parameters
----------------
only_seldom_used_keywords : type, optional
Explanation
common_parameters_listed_above : type, optional
Explanation
"""
)
assert len(docstring.meta) == 2
assert docstring.meta[0].args == [
"other_param",
"only_seldom_used_keywords",
]
assert docstring.meta[0].arg_name == "only_seldom_used_keywords"
assert docstring.meta[0].type_name == "type"
assert docstring.meta[0].is_optional
assert docstring.meta[0].description == "Explanation"
assert docstring.meta[1].args == [
"other_param",
"common_parameters_listed_above",
]
def test_yields() -> None:
"""Test parsing yields."""
docstring = parse(
"""
Short description
Yields
------
int
description
"""
)
assert len(docstring.meta) == 1
assert docstring.meta[0].args == ["yields"]
assert docstring.meta[0].type_name == "int"
assert docstring.meta[0].description == "description"
assert docstring.meta[0].return_name is None
assert docstring.meta[0].is_generator
def test_returns() -> None:
"""Test parsing returns."""
docstring = parse(
"""
Short description
"""
)
assert docstring.returns is None
assert docstring.many_returns is not None
assert len(docstring.many_returns) == 0
docstring = parse(
"""
Short description
Returns
-------
type
"""
)
assert docstring.returns is not None
assert docstring.returns.type_name == "type"
assert docstring.returns.description is None
assert docstring.many_returns is not None
assert len(docstring.many_returns) == 1
assert docstring.many_returns[0] == docstring.returns
docstring = parse(
"""
Short description
Returns
-------
int
description
"""
)
assert docstring.returns is not None
assert docstring.returns.type_name == "int"
assert docstring.returns.description == "description"
assert docstring.many_returns is not None
assert len(docstring.many_returns) == 1
assert docstring.many_returns[0] == docstring.returns
docstring = parse(
"""
Returns
-------
Optional[Mapping[str, List[int]]]
A description: with a colon
"""
)
assert docstring.returns is not None
assert docstring.returns.type_name == "Optional[Mapping[str, List[int]]]"
assert docstring.returns.description == "A description: with a colon"
assert docstring.many_returns is not None
assert len(docstring.many_returns) == 1
assert docstring.many_returns[0] == docstring.returns
docstring = parse(
"""
Short description
Returns
-------
int
description
with much text
even some spacing
"""
)
assert docstring.returns is not None
assert docstring.returns.type_name == "int"
assert docstring.returns.description == (
"description\nwith much text\n\neven some spacing"
)
assert docstring.many_returns is not None
assert len(docstring.many_returns) == 1
assert docstring.many_returns[0] == docstring.returns
docstring = parse(
"""
Short description
Returns
-------
a : int
description for a
b : str
description for b
"""
)
assert docstring.returns is not None
assert docstring.returns.type_name == "int"
assert docstring.returns.description == ("description for a")
assert docstring.many_returns is not None
assert len(docstring.many_returns) == 2
assert docstring.many_returns[0].type_name == "int"
assert docstring.many_returns[0].description == "description for a"
assert docstring.many_returns[0].return_name == "a"
assert docstring.many_returns[1].type_name == "str"
assert docstring.many_returns[1].description == "description for b"
assert docstring.many_returns[1].return_name == "b"
def test_raises() -> None:
"""Test parsing raises."""
docstring = parse(
"""
Short description
"""
)
assert len(docstring.raises) == 0
docstring = parse(
"""
Short description
Raises
------
ValueError
description
"""
)
assert len(docstring.raises) == 1
assert docstring.raises[0].type_name == "ValueError"
assert docstring.raises[0].description == "description"
def test_warns() -> None:
"""Test parsing warns."""
docstring = parse(
"""
Short description
Warns
-----
UserWarning
description
"""
)
assert len(docstring.meta) == 1
assert docstring.meta[0].type_name == "UserWarning"
assert docstring.meta[0].description == "description"
def test_simple_sections() -> None:
"""Test parsing simple sections."""
docstring = parse(
"""
Short description
See Also
--------
something : some thing you can also see
actually, anything can go in this section
Warnings
--------
Here be dragons
Notes
-----
None of this is real
References
----------
Cite the relevant literature, e.g. [1]_. You may also cite these
references in the notes section above.
.. [1] O. McNoleg, "The integration of GIS, remote sensing,
expert systems and adaptive co-kriging for environmental habitat
modelling of the Highland Haggis using object-oriented, fuzzy-logic
and neural-network techniques," Computers & Geosciences, vol. 22,
pp. 585-588, 1996.
"""
)
assert len(docstring.meta) == 4
assert docstring.meta[0].args == ["see_also"]
assert docstring.meta[0].description == (
"something : some thing you can also see\n"
"actually, anything can go in this section"
)
assert docstring.meta[1].args == ["warnings"]
assert docstring.meta[1].description == "Here be dragons"
assert docstring.meta[2].args == ["notes"]
assert docstring.meta[2].description == "None of this is real"
assert docstring.meta[3].args == ["references"]
@pytest.mark.parametrize(
"source, expected_results",
[
(
"Description\nExamples\n--------\nlong example\n\nmore here",
[
(None, "long example\n\nmore here"),
],
),
(
"Description\nExamples\n--------\n>>> test",
[
(">>> test", ""),
],
),
(
"Description\nExamples\n--------\n>>> testa\n>>> testb",
[
(">>> testa\n>>> testb", ""),
],
),
(
"Description\nExamples\n--------\n>>> test1\ndesc1",
[
(">>> test1", "desc1"),
],
),
(
"Description\nExamples\n--------\n"
">>> test1a\n>>> test1b\ndesc1a\ndesc1b",
[
(">>> test1a\n>>> test1b", "desc1a\ndesc1b"),
],
),
(
"Description\nExamples\n--------\n"
">>> test1\ndesc1\n>>> test2\ndesc2",
[
(">>> test1", "desc1"),
(">>> test2", "desc2"),
],
),
(
"Description\nExamples\n--------\n"
">>> test1a\n>>> test1b\ndesc1a\ndesc1b\n"
">>> test2a\n>>> test2b\ndesc2a\ndesc2b\n",
[
(">>> test1a\n>>> test1b", "desc1a\ndesc1b"),
(">>> test2a\n>>> test2b", "desc2a\ndesc2b"),
],
),
(
"Description\nExamples\n--------\n"
" >>> test1a\n >>> test1b\n desc1a\n desc1b\n"
" >>> test2a\n >>> test2b\n desc2a\n desc2b\n",
[
(">>> test1a\n>>> test1b", "desc1a\ndesc1b"),
(">>> test2a\n>>> test2b", "desc2a\ndesc2b"),
],
),
],
)
def test_examples(
source, expected_results: T.List[T.Tuple[T.Optional[str], str]]
) -> None:
"""Test parsing examples."""
docstring = parse(source)
assert len(docstring.meta) == len(expected_results)
for meta, expected_result in zip(docstring.meta, expected_results):
assert meta.description == expected_result[1]
assert len(docstring.examples) == len(expected_results)
for example, expected_result in zip(docstring.examples, expected_results):
assert example.snippet == expected_result[0]
assert example.description == expected_result[1]
@pytest.mark.parametrize(
"source, expected_depr_version, expected_depr_desc",
[
(
"Short description\n\n.. deprecated:: 1.6.0\n This is busted!",
"1.6.0",
"This is busted!",
),
(
(
"Short description\n\n"
".. deprecated:: 1.6.0\n"
" This description has\n"
" multiple lines!"
),
"1.6.0",
"This description has\nmultiple lines!",
),
("Short description\n\n.. deprecated:: 1.6.0", "1.6.0", None),
(
"Short description\n\n.. deprecated::\n No version!",
None,
"No version!",
),
],
)
def test_deprecation(
source: str,
expected_depr_version: T.Optional[str],
expected_depr_desc: T.Optional[str],
) -> None:
"""Test parsing deprecation notes."""
docstring = parse(source)
assert docstring.deprecation is not None
assert docstring.deprecation.version == expected_depr_version
assert docstring.deprecation.description == expected_depr_desc
@pytest.mark.parametrize(
"source, expected",
[
("", ""),
("\n", ""),
("Short description", "Short description"),
("\nShort description\n", "Short description"),
("\n Short description\n", "Short description"),
(
"Short description\n\nLong description",
"Short description\n\nLong description",
),
(
"""
Short description
Long description
""",
"Short description\n\nLong description",
),
(
"""
Short description
Long description
Second line
""",
"Short description\n\nLong description\nSecond line",
),
(
"Short description\nLong description",
"Short description\nLong description",
),
(
"""
Short description
Long description
""",
"Short description\nLong description",
),
(
"\nShort description\nLong description\n",
"Short description\nLong description",
),
(
"""
Short description
Long description
Second line
""",
"Short description\nLong description\nSecond line",
),
(
"""
Short description
Meta:
-----
asd
""",
"Short description\nMeta:\n-----\n asd",
),
(
"""
Short description
Long description
Meta:
-----
asd
""",
"Short description\n"
"Long description\n"
"Meta:\n"
"-----\n"
" asd",
),
(
"""
Short description
First line
Second line
Meta:
-----
asd
""",
"Short description\n"
"First line\n"
" Second line\n"
"Meta:\n"
"-----\n"
" asd",
),
(
"""
Short description
First line
Second line
Meta:
-----
asd
""",
"Short description\n"
"\n"
"First line\n"
" Second line\n"
"Meta:\n"
"-----\n"
" asd",
),
(
"""
Short description
First line
Second line
Meta:
-----
asd
""",
"Short description\n"
"\n"
"First line\n"
" Second line\n"
"\n"
"Meta:\n"
"-----\n"
" asd",
),
(
"""
Short description
Meta:
-----
asd
1
2
3
""",
"Short description\n"
"\n"
"Meta:\n"
"-----\n"
" asd\n"
" 1\n"
" 2\n"
" 3",
),
(
"""
Short description
Meta1:
------
asd
1
2
3
Meta2:
------
herp
Meta3:
------
derp
""",
"Short description\n"
"\n"
"Meta1:\n"
"------\n"
" asd\n"
" 1\n"
" 2\n"
" 3\n"
"Meta2:\n"
"------\n"
" herp\n"
"Meta3:\n"
"------\n"
" derp",
),
(
"""
Short description
Parameters:
-----------
name
description 1
priority: int
description 2
sender: str, optional
description 3
message: str, optional
description 4, defaults to 'hello'
multiline: str, optional
long description 5,
defaults to 'bye'
""",
"Short description\n"
"\n"
"Parameters:\n"
"-----------\n"
" name\n"
" description 1\n"
" priority: int\n"
" description 2\n"
" sender: str, optional\n"
" description 3\n"
" message: str, optional\n"
" description 4, defaults to 'hello'\n"
" multiline: str, optional\n"
" long description 5,\n"
" defaults to 'bye'",
),
(
"""
Short description
Raises:
-------
ValueError
description
""",
"Short description\n"
"Raises:\n"
"-------\n"
" ValueError\n"
" description",
),
(
"""
Description
Examples:
--------
>>> test1a
>>> test1b
desc1a
desc1b
>>> test2a
>>> test2b
desc2a
desc2b
""",
"Description\n"
"Examples:\n"
"--------\n"
">>> test1a\n"
">>> test1b\n"
"desc1a\n"
"desc1b\n"
">>> test2a\n"
">>> test2b\n"
"desc2a\n"
"desc2b",
),
],
)
def test_compose(source: str, expected: str) -> None:
"""Test compose in default mode."""
assert compose(parse(source)) == expected