Files
2026-07-13 13:17:40 +08:00

215 lines
5.7 KiB
Python

import sys
import pytest
from ci.ray_ci.doc.api import (
_SPHINX_AUTOCLASS_HEADER,
_SPHINX_AUTOSUMMARY_HEADER,
API,
AnnotationType,
CodeType,
)
from ci.ray_ci.doc.mock.mock_module import mock_function
def test_from_autosummary():
test_data = [
{
"input": {
"doc": (
f"{_SPHINX_AUTOSUMMARY_HEADER}\n"
"\t:toc\n"
"\n"
"\tfun_01\n"
"\t.. this is a comment\n"
"\tfun_02\n"
"something else"
),
"module": "mymodule",
},
"output": [
API(
name="mymodule.fun_01",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.FUNCTION,
),
API(
name="mymodule.fun_02",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.FUNCTION,
),
],
},
{
"input": {
"doc": "invalid string",
"module": "mymodule",
},
"output": [],
},
]
for test in test_data:
assert str(
API.from_autosummary(
test["input"]["doc"],
test["input"]["module"],
)
) == str(test["output"])
def test_from_autoclasss():
test_data = [
# valid input, no module
{
"input": {
"doc": f"{_SPHINX_AUTOCLASS_HEADER} myclass",
"module": None,
},
"output": API(
name="myclass",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.CLASS,
),
},
# valid input, with module
{
"input": {
"doc": f"{_SPHINX_AUTOCLASS_HEADER} myclass",
"module": "mymodule",
},
"output": API(
name="mymodule.myclass",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.CLASS,
),
},
# invalid input
{
"input": {
"doc": "invalid",
"module": None,
},
"output": None,
},
]
for test in test_data:
assert str(
API.from_autoclass(
test["input"]["doc"],
test["input"]["module"],
)
) == str(test["output"])
def test_get_canonical_name():
api = API(
name="ci.ray_ci.doc.mock.mock_function",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.FUNCTION,
)
assert (
api.get_canonical_name()
== f"{mock_function.__module__}.{mock_function.__qualname__}"
)
def test_is_private_name():
test_data = [
{
"input": "a.b._private_function",
"output": True,
},
{
"input": "a.b._internal.public_function",
"output": True,
},
{
"input": "b.c.public_class",
"output": False,
},
]
for test in test_data:
assert (
API(
name=test["input"],
annotation_type=AnnotationType.UNKNOWN,
code_type=CodeType.FUNCTION,
)._is_private_name()
== test["output"]
)
def test_is_public():
assert not API(
name="a.b._private_function",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.FUNCTION,
).is_public()
assert not API(
name="a.b._internal.public_function",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.FUNCTION,
).is_public()
assert not API(
name="a.b.public_function",
annotation_type=AnnotationType.DEPRECATED,
code_type=CodeType.FUNCTION,
).is_public()
assert API(
name="a.b.public_function",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.FUNCTION,
).is_public()
def test_is_deprecated():
assert not API(
name="a.b._private_function",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.FUNCTION,
).is_deprecated()
assert API(
name="a.b.function",
annotation_type=AnnotationType.DEPRECATED,
code_type=CodeType.FUNCTION,
).is_deprecated()
def test_split_good_and_bad_apis():
good_apis, bad_apis = API.split_good_and_bad_apis(
{
"a.b.public_function": API(
name="a.b.public_function",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.FUNCTION,
),
"a.b._private_function": API(
name="a.b._private_function",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.FUNCTION,
),
"a.b.deprecated_function_01": API(
name="a.b.deprecated_function_01",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.FUNCTION,
),
"a.b.deprecated_function_02": API(
name="a.b.deprecated_function_02",
annotation_type=AnnotationType.PUBLIC_API,
code_type=CodeType.FUNCTION,
),
},
{"a.b.public_function"},
{"a.b._private_function"},
)
assert good_apis == ["a.b.public_function"]
assert bad_apis == ["a.b.deprecated_function_01", "a.b.deprecated_function_02"]
if __name__ == "__main__":
sys.exit(pytest.main(["-v", __file__]))