mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 03:24:20 +00:00
⚗️ Write more tests, why do they crash
This commit is contained in:
parent
9b4b382145
commit
b8705c59cd
3 changed files with 161 additions and 31 deletions
|
@ -42,12 +42,11 @@ class Blueprint(metaclass=abc.ABCMeta):
|
|||
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def __init__(self):
|
||||
"""
|
||||
:return: The created object.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def __hash__(self):
|
||||
|
|
|
@ -112,7 +112,7 @@ class Filter:
|
|||
return decorated
|
||||
return decorator
|
||||
|
||||
def map(self, c: Callable[[Any], bool]) -> Filter:
|
||||
def map(self, c: Callable[[Any], object]) -> Filter:
|
||||
"""
|
||||
Apply the function ``c`` on all objects transiting through the queue:
|
||||
- If the function **returns**, its return value replaces the object in the queue;
|
||||
|
@ -184,18 +184,6 @@ class Filter:
|
|||
"""
|
||||
return self.requires(blueprints.Message.text).map(lambda o: o.text())
|
||||
|
||||
@staticmethod
|
||||
def _deco_startswith(prefix: str):
|
||||
def decorator(func):
|
||||
@functools.wraps(func)
|
||||
def decorated(obj):
|
||||
result: str = func(obj)
|
||||
if not result.startswith(prefix):
|
||||
raise exc.Discard(result, f"Text didn't start with {prefix}")
|
||||
return result
|
||||
return decorated
|
||||
return decorator
|
||||
|
||||
def startswith(self, prefix: str):
|
||||
"""
|
||||
Check if an object starts with the specified prefix and discard the objects that do not.
|
||||
|
@ -203,20 +191,16 @@ class Filter:
|
|||
:param prefix: The prefix object should start with.
|
||||
:return: A new :class:`Filter` with the new requirements.
|
||||
"""
|
||||
return self.__class__(self._deco_startswith(prefix)(self.func))
|
||||
return self.filter(lambda x: x.startswith(prefix), error=f"Text didn't start with {prefix}")
|
||||
|
||||
@staticmethod
|
||||
def _deco_regex(pattern: Pattern):
|
||||
def decorator(func):
|
||||
@functools.wraps(func)
|
||||
def decorated(obj):
|
||||
result: str = func(obj)
|
||||
if match := pattern.match(result):
|
||||
return match
|
||||
else:
|
||||
raise exc.Discard(result, f"Text didn't match pattern {pattern}")
|
||||
return decorated
|
||||
return decorator
|
||||
def endswith(self, suffix: str):
|
||||
"""
|
||||
Check if an object ends with the specified suffix and discard the objects that do not.
|
||||
|
||||
:param suffix: The prefix object should start with.
|
||||
:return: A new :class:`Filter` with the new requirements.
|
||||
"""
|
||||
return self.filter(lambda x: x.endswith(suffix), error=f"Text didn't end with {suffix}")
|
||||
|
||||
def regex(self, pattern: Pattern):
|
||||
"""
|
||||
|
@ -225,7 +209,13 @@ class Filter:
|
|||
:param pattern: The pattern that should be matched by the text.
|
||||
:return: A new :class:`Filter` with the new requirements.
|
||||
"""
|
||||
return self.__class__(self._deco_regex(pattern)(self.func))
|
||||
def mapping(x):
|
||||
if match := pattern.match(x):
|
||||
return match
|
||||
else:
|
||||
raise exc.Discard(x, f"Text didn't match pattern {pattern}")
|
||||
|
||||
return self.map(mapping)
|
||||
|
||||
def choices(self, *choices):
|
||||
"""
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import pytest
|
||||
import asyncio
|
||||
import async_timeout
|
||||
from .. import sentry, exc
|
||||
import re
|
||||
from .. import sentry, exc, blueprints
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -40,6 +41,14 @@ def discarding_filter() -> sentry.Filter:
|
|||
return sentry.Filter(discard)
|
||||
|
||||
|
||||
class ErrorTest(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def error_test(*_, **__):
|
||||
raise ErrorTest("This was raised by error_raiser.")
|
||||
|
||||
|
||||
class TestFilter:
|
||||
def test_creation(self):
|
||||
f = sentry.Filter(lambda _: _)
|
||||
|
@ -66,5 +75,137 @@ class TestFilter:
|
|||
@pytest.mark.asyncio
|
||||
async def test_timeout(self, s: sentry.Sentry):
|
||||
with pytest.raises(asyncio.TimeoutError):
|
||||
async with async_timeout.timeout(0.05):
|
||||
async with async_timeout.timeout(0.001):
|
||||
await s.f().get()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_filter(self, s: sentry.Sentry):
|
||||
await s.queue.put(None)
|
||||
await s.queue.put(None)
|
||||
|
||||
assert await s.f().filter(lambda x: x is None, "Is not None").get_single() is None
|
||||
|
||||
with pytest.raises(exc.Discard):
|
||||
await s.f().filter(lambda x: isinstance(x, type), error="Is not type").get_single()
|
||||
|
||||
with pytest.raises(ErrorTest):
|
||||
await s.f().filter(error_test, error="Is error").get_single()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_map(self, s: sentry.Sentry):
|
||||
await s.queue.put(None)
|
||||
await s.queue.put(None)
|
||||
|
||||
assert await s.f().map(lambda x: 1).get_single() == 1
|
||||
|
||||
with pytest.raises(ErrorTest):
|
||||
await s.f().map(error_test).get_single()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_type(self, s: sentry.Sentry):
|
||||
await s.queue.put(1)
|
||||
await s.queue.put("no")
|
||||
|
||||
assert await s.f().type(int).get_single() == 1
|
||||
|
||||
with pytest.raises(exc.Discard):
|
||||
await s.f().type(int).get_single()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_msg(self, s: sentry.Sentry):
|
||||
class ExampleMessage(blueprints.Message):
|
||||
def __hash__(self):
|
||||
return 1
|
||||
|
||||
msg = ExampleMessage()
|
||||
await s.queue.put(msg)
|
||||
await s.queue.put("no")
|
||||
|
||||
assert await s.f().msg().get_single() is msg
|
||||
|
||||
with pytest.raises(exc.Discard):
|
||||
await s.f().msg().get_single()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_requires(self, s: sentry.Sentry):
|
||||
class AvailableMessage(blueprints.Message):
|
||||
def __hash__(self):
|
||||
return 1
|
||||
|
||||
def text(self) -> str:
|
||||
return "1"
|
||||
|
||||
class NotAvailableMessage(blueprints.Message):
|
||||
def __hash__(self):
|
||||
return 2
|
||||
|
||||
def text(self) -> str:
|
||||
raise exc.NotAvailableError()
|
||||
|
||||
class NeverAvailableMessage(blueprints.Message):
|
||||
def __hash__(self):
|
||||
return 3
|
||||
|
||||
avmsg = AvailableMessage()
|
||||
namsg = NotAvailableMessage()
|
||||
nvmsg = NeverAvailableMessage()
|
||||
|
||||
await s.queue.put(avmsg)
|
||||
await s.queue.put(namsg)
|
||||
await s.queue.put(nvmsg)
|
||||
await s.queue.put(namsg)
|
||||
await s.queue.put(nvmsg)
|
||||
|
||||
assert await s.f().requires(blueprints.Message.text).get_single() is avmsg
|
||||
|
||||
with pytest.raises(exc.Discard):
|
||||
await s.f().requires(blueprints.Message.text).get_single()
|
||||
|
||||
with pytest.raises(exc.NeverAvailableError):
|
||||
await s.f().requires(blueprints.Message.text).get_single()
|
||||
|
||||
with pytest.raises(exc.NotAvailableError):
|
||||
await s.f().requires(blueprints.Message.text, propagate_not_available=True).get_single()
|
||||
|
||||
with pytest.raises(exc.Discard):
|
||||
await s.f().requires(blueprints.Message.text, propagate_never_available=False).get_single()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_startswith(self, s: sentry.Sentry):
|
||||
await s.queue.put("yarrharr")
|
||||
await s.queue.put("yohoho")
|
||||
|
||||
assert await s.f().startswith("yarr").get_single() == "yarrharr"
|
||||
|
||||
with pytest.raises(exc.Discard):
|
||||
await s.f().startswith("yarr").get_single()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_endswith(self, s: sentry.Sentry):
|
||||
await s.queue.put("yarrharr")
|
||||
await s.queue.put("yohoho")
|
||||
|
||||
assert await s.f().endswith("harr").get_single() == "yarrharr"
|
||||
|
||||
with pytest.raises(exc.Discard):
|
||||
await s.f().endswith("harr").get_single()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_regex(self, s: sentry.Sentry):
|
||||
await s.queue.put("yarrharr")
|
||||
await s.queue.put("yohoho")
|
||||
|
||||
assert isinstance(await s.f().regex(re.compile(r"[yh]arr")).get_single(), re.Match)
|
||||
|
||||
with pytest.raises(exc.Discard):
|
||||
await s.f().regex(re.compile(r"[yh]arr")).get_single()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_choices(self, s: sentry.Sentry):
|
||||
await s.queue.put("yarrharr")
|
||||
await s.queue.put("yohoho")
|
||||
|
||||
assert await s.f().choices("yarrharr", "banana").get_single() == "yarrharr"
|
||||
|
||||
with pytest.raises(exc.Discard):
|
||||
await s.f().choices("yarrharr", "banana").get_single()
|
||||
|
|
Loading…
Reference in a new issue