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):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
:return: The created object.
|
:return: The created object.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
pass
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
|
|
|
@ -112,7 +112,7 @@ class Filter:
|
||||||
return decorated
|
return decorated
|
||||||
return decorator
|
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:
|
Apply the function ``c`` on all objects transiting through the queue:
|
||||||
- If the function **returns**, its return value replaces the object in 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())
|
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):
|
def startswith(self, prefix: str):
|
||||||
"""
|
"""
|
||||||
Check if an object starts with the specified prefix and discard the objects that do not.
|
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.
|
:param prefix: The prefix object should start with.
|
||||||
:return: A new :class:`Filter` with the new requirements.
|
: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 endswith(self, suffix: str):
|
||||||
def _deco_regex(pattern: Pattern):
|
"""
|
||||||
def decorator(func):
|
Check if an object ends with the specified suffix and discard the objects that do not.
|
||||||
@functools.wraps(func)
|
|
||||||
def decorated(obj):
|
:param suffix: The prefix object should start with.
|
||||||
result: str = func(obj)
|
:return: A new :class:`Filter` with the new requirements.
|
||||||
if match := pattern.match(result):
|
"""
|
||||||
return match
|
return self.filter(lambda x: x.endswith(suffix), error=f"Text didn't end with {suffix}")
|
||||||
else:
|
|
||||||
raise exc.Discard(result, f"Text didn't match pattern {pattern}")
|
|
||||||
return decorated
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
def regex(self, pattern: Pattern):
|
def regex(self, pattern: Pattern):
|
||||||
"""
|
"""
|
||||||
|
@ -225,7 +209,13 @@ class Filter:
|
||||||
:param pattern: The pattern that should be matched by the text.
|
:param pattern: The pattern that should be matched by the text.
|
||||||
:return: A new :class:`Filter` with the new requirements.
|
: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):
|
def choices(self, *choices):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import pytest
|
import pytest
|
||||||
import asyncio
|
import asyncio
|
||||||
import async_timeout
|
import async_timeout
|
||||||
from .. import sentry, exc
|
import re
|
||||||
|
from .. import sentry, exc, blueprints
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -40,6 +41,14 @@ def discarding_filter() -> sentry.Filter:
|
||||||
return sentry.Filter(discard)
|
return sentry.Filter(discard)
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorTest(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def error_test(*_, **__):
|
||||||
|
raise ErrorTest("This was raised by error_raiser.")
|
||||||
|
|
||||||
|
|
||||||
class TestFilter:
|
class TestFilter:
|
||||||
def test_creation(self):
|
def test_creation(self):
|
||||||
f = sentry.Filter(lambda _: _)
|
f = sentry.Filter(lambda _: _)
|
||||||
|
@ -66,5 +75,137 @@ class TestFilter:
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_timeout(self, s: sentry.Sentry):
|
async def test_timeout(self, s: sentry.Sentry):
|
||||||
with pytest.raises(asyncio.TimeoutError):
|
with pytest.raises(asyncio.TimeoutError):
|
||||||
async with async_timeout.timeout(0.05):
|
async with async_timeout.timeout(0.001):
|
||||||
await s.f().get()
|
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