Skip to content

Commit

Permalink
Fixed bug with merging of different routers; Added test
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelkryukov committed Apr 18, 2020
1 parent e6aafb0 commit 5276703
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 8 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog

> Changes to public API is marked as `^`
> Changes to public API is marked as `^`. Possible changes to public API is marked as `^?`.
- v4.1.6
- ^? Fixed merging of 'different' routers
- Added tests for routers merges

- v4.1.5
- Fixed `.send_message` with long messages.
Expand Down
11 changes: 11 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ their methods for these classes in Full API.
You can find descriptions of all possible "on_*" methods for adding your
callbacks in :class:`kutana.plugin.Plugin` class.

Order of "on_*" methods
^^^^^^^^^^^^^^^^^^^^^^^
Default order of processors:

- on_any_message: 9
- on_payload (vk): 7
- on_commands: 6
- on_attachments: 3
- on_any_unprocessed_message: -3
- Rest: ~0

Attachments
^^^^^^^^^^^

Expand Down
2 changes: 1 addition & 1 deletion kutana/kutana.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def _init_routers(self):

def _add_router(new_router):
for router in self._routers:
if isinstance(router, new_router.__class__):
if type(router) is type(new_router) and router.priority == new_router.priority:
router.merge(new_router)
return

Expand Down
14 changes: 9 additions & 5 deletions kutana/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ def _key(self, handler):
-handler.priority,
)

def _assert_routers_alike(self, other_router):
if type(other_router) is not type(self):
raise RuntimeError("Can't merge routers with different classes")

if other_router.priority != self.priority:
raise RuntimeError("Can't merge routers with different priorities")

def _check_update(self, update, ctx):
"""Should update be processed?"""
return True
Expand Down Expand Up @@ -46,9 +53,7 @@ def add_handler(self, handler):
self._handlers.add(handler)

def merge(self, other_router):
if not isinstance(other_router, self.__class__):
raise RuntimeError("Can't merge routers with different classes")

self._assert_routers_alike(other_router)
self._handlers.update(other_router._handlers)

async def handle(self, update, ctx):
Expand Down Expand Up @@ -85,8 +90,7 @@ def add_handler(self, handler, key):
self._handlers[key] = SortedList([handler], key=self._key)

def merge(self, other_router):
if not isinstance(other_router, self.__class__):
raise RuntimeError("Can't merge routers with different classes")
self._assert_routers_alike(other_router)

for key, handlers in other_router._handlers.items():
for handler in handlers:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import setuptools


VERSION = "4.1.5"
VERSION = "4.1.6"


with open("README.md", "r") as fh:
Expand Down
64 changes: 64 additions & 0 deletions tests/test_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from kutana import Context
from kutana.handler import Handler
from kutana.router import Router, ListRouter, MapRouter
from kutana.routers import AnyMessageRouter, AnyUnprocessedMessageRouter


def test_check():
Expand Down Expand Up @@ -52,3 +53,66 @@ def test_router_merge():

assert len(mr1._handlers["a"]) == 2
assert len(mr1._handlers["b"]) == 1


def test_router_subclass_merge():
mr1 = AnyMessageRouter()
mr2 = AnyUnprocessedMessageRouter()
mr3 = ListRouter()
mr4 = AnyMessageRouter()

mr1.add_handler(Handler(1, "*", "*", 0))
mr1.add_handler(Handler(2, "*", "*", 0))
mr2.add_handler(Handler(3, "*", "*", 0))
mr3.add_handler(Handler(4, "*", "*", 0))
mr4.add_handler(Handler(5, "*", "*", 0))

with pytest.raises(RuntimeError):
mr1.merge(mr2)

with pytest.raises(RuntimeError):
mr1.merge(mr3)

with pytest.raises(RuntimeError):
mr2.merge(mr3)

mr4.merge(mr1)

assert len(mr1._handlers) == 2
assert len(mr2._handlers) == 1
assert len(mr3._handlers) == 1
assert len(mr4._handlers) == 3
assert set(map(lambda h: h.handle, mr4._handlers)) == {5, 1, 2}


def test_router_merge_priority():
mr1 = AnyMessageRouter(priority=9)
mr2 = AnyMessageRouter(priority=7)
mr3 = AnyMessageRouter(priority=5)
mr4 = AnyMessageRouter(priority=5)

mr1.add_handler(Handler(1, "*", "*", 0))
mr2.add_handler(Handler(2, "*", "*", 0))
mr3.add_handler(Handler(3, "*", "*", 0))
mr3.add_handler(Handler(4, "*", "*", 5))
mr4.add_handler(Handler(5, "*", "*", 3))
mr4.add_handler(Handler(6, "*", "*", 10))

with pytest.raises(RuntimeError):
mr1.merge(mr2)

with pytest.raises(RuntimeError):
mr1.merge(mr3)

with pytest.raises(RuntimeError):
mr2.merge(mr3)

mr3.merge(mr4)

handlers = list(map(lambda h: h.handle, [
*mr1._handlers,
*mr2._handlers,
*mr3._handlers,
]))

assert handlers == [1, 2, 6, 4, 5, 3]

0 comments on commit 5276703

Please sign in to comment.