mirror of
https://github.com/nonebot/nonebot2.git
synced 2026-04-14 20:47:18 +00:00
Co-authored-by: Ju4tCode <42488585+yanyongyu@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
158 lines
4.4 KiB
Python
158 lines
4.4 KiB
Python
import copy
|
|
import json
|
|
import pickle
|
|
from typing import ClassVar, Dict, List, Literal, TypeVar, Union # noqa: UP035
|
|
|
|
from pydantic import ValidationError
|
|
import pytest
|
|
|
|
from nonebot.compat import type_validate_python
|
|
from nonebot.utils import (
|
|
UNSET,
|
|
DataclassEncoder,
|
|
Unset,
|
|
UnsetType,
|
|
escape_tag,
|
|
exclude_unset,
|
|
generic_check_issubclass,
|
|
is_async_gen_callable,
|
|
is_coroutine_callable,
|
|
is_gen_callable,
|
|
)
|
|
from utils import FakeMessage, FakeMessageSegment
|
|
|
|
|
|
def test_unset():
|
|
assert isinstance(UNSET, Unset)
|
|
assert bool(UNSET) is False
|
|
assert copy.copy(UNSET) is UNSET
|
|
assert copy.deepcopy(UNSET) is UNSET
|
|
assert pickle.loads(pickle.dumps(UNSET)) is UNSET
|
|
assert type_validate_python(UnsetType, UNSET) is UNSET
|
|
|
|
with pytest.raises(ValidationError):
|
|
type_validate_python(UnsetType, 123)
|
|
|
|
|
|
def test_exclude_unset():
|
|
assert exclude_unset({"a": 1, "b": UNSET, "c": None, "d": {"x": UNSET}}) == {
|
|
"a": 1,
|
|
"c": None,
|
|
"d": {},
|
|
}
|
|
assert exclude_unset([1, UNSET, None, {"x": UNSET}]) == [1, None, {}]
|
|
assert exclude_unset(UNSET) is None
|
|
assert exclude_unset(123) == 123
|
|
|
|
|
|
def test_loguru_escape_tag():
|
|
assert escape_tag("<red>red</red>") == r"\<red>red\</red>"
|
|
assert escape_tag("<fg #fff>white</fg #fff>") == r"\<fg #fff>white\</fg #fff>"
|
|
assert escape_tag("<fg\n#fff>white</fg\n#fff>") == "\\<fg\n#fff>white\\</fg\n#fff>"
|
|
assert escape_tag("<bg #fff>white</bg #fff>") == r"\<bg #fff>white\</bg #fff>"
|
|
assert escape_tag("<bg\n#fff>white</bg\n#fff>") == "\\<bg\n#fff>white\\</bg\n#fff>"
|
|
|
|
|
|
def test_generic_check_issubclass():
|
|
assert generic_check_issubclass(int, (int, float))
|
|
assert not generic_check_issubclass(str, (int, float))
|
|
assert generic_check_issubclass(Union[int, float, None], (int, float)) # noqa: UP007
|
|
assert generic_check_issubclass(int | float | None, (int, float))
|
|
assert generic_check_issubclass(Literal[1, 2, 3], int)
|
|
assert not generic_check_issubclass(Literal[1, 2, "3"], int)
|
|
assert generic_check_issubclass(List[int], list) # noqa: UP006
|
|
assert generic_check_issubclass(Dict[str, int], dict) # noqa: UP006
|
|
assert generic_check_issubclass(list[int], list)
|
|
assert generic_check_issubclass(dict[str, int], dict)
|
|
assert not generic_check_issubclass(ClassVar[int], int)
|
|
assert generic_check_issubclass(TypeVar("T", int, float), (int, float))
|
|
assert generic_check_issubclass(TypeVar("T", bound=int), (int, float))
|
|
|
|
|
|
def test_is_coroutine_callable():
|
|
async def test1(): ...
|
|
|
|
def test2(): ...
|
|
|
|
class TestClass1:
|
|
async def __call__(self): ...
|
|
|
|
class TestClass2:
|
|
def __call__(self): ...
|
|
|
|
assert is_coroutine_callable(test1)
|
|
assert not is_coroutine_callable(test2)
|
|
assert not is_coroutine_callable(TestClass1)
|
|
assert is_coroutine_callable(TestClass1())
|
|
assert not is_coroutine_callable(TestClass2)
|
|
|
|
|
|
def test_is_gen_callable():
|
|
def test1():
|
|
yield
|
|
|
|
async def test2():
|
|
yield
|
|
|
|
def test3(): ...
|
|
|
|
class TestClass1:
|
|
def __call__(self):
|
|
yield
|
|
|
|
class TestClass2:
|
|
async def __call__(self):
|
|
yield
|
|
|
|
class TestClass3:
|
|
def __call__(self): ...
|
|
|
|
assert is_gen_callable(test1)
|
|
assert not is_gen_callable(test2)
|
|
assert not is_gen_callable(test3)
|
|
assert is_gen_callable(TestClass1())
|
|
assert not is_gen_callable(TestClass2())
|
|
assert not is_gen_callable(TestClass3())
|
|
|
|
|
|
def test_is_async_gen_callable():
|
|
async def test1():
|
|
yield
|
|
|
|
def test2():
|
|
yield
|
|
|
|
async def test3(): ...
|
|
|
|
class TestClass1:
|
|
async def __call__(self):
|
|
yield
|
|
|
|
class TestClass2:
|
|
def __call__(self):
|
|
yield
|
|
|
|
class TestClass3:
|
|
async def __call__(self): ...
|
|
|
|
assert is_async_gen_callable(test1)
|
|
assert not is_async_gen_callable(test2)
|
|
assert not is_async_gen_callable(test3)
|
|
assert is_async_gen_callable(TestClass1())
|
|
assert not is_async_gen_callable(TestClass2())
|
|
assert not is_async_gen_callable(TestClass3())
|
|
|
|
|
|
def test_dataclass_encoder():
|
|
simple = json.dumps("123", cls=DataclassEncoder)
|
|
assert simple == '"123"'
|
|
|
|
ms = FakeMessageSegment.nested(FakeMessage(FakeMessageSegment.text("text")))
|
|
s = json.dumps(ms, cls=DataclassEncoder)
|
|
assert s == (
|
|
"{"
|
|
'"type": "node", '
|
|
'"data": {"content": [{"type": "text", "data": {"text": "text"}}]}'
|
|
"}"
|
|
)
|