Skip to content

Commit 5276703

Browse files
committedApr 18, 2020
Fixed bug with merging of different routers; Added test
1 parent e6aafb0 commit 5276703

File tree

6 files changed

+91
-8
lines changed

6 files changed

+91
-8
lines changed
 

‎CHANGELOG.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Changelog
22

3-
> Changes to public API is marked as `^`
3+
> Changes to public API is marked as `^`. Possible changes to public API is marked as `^?`.
4+
5+
- v4.1.6
6+
- ^? Fixed merging of 'different' routers
7+
- Added tests for routers merges
48

59
- v4.1.5
610
- Fixed `.send_message` with long messages.

‎docs/index.rst

+11
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ their methods for these classes in Full API.
6969
You can find descriptions of all possible "on_*" methods for adding your
7070
callbacks in :class:`kutana.plugin.Plugin` class.
7171

72+
Order of "on_*" methods
73+
^^^^^^^^^^^^^^^^^^^^^^^
74+
Default order of processors:
75+
76+
- on_any_message: 9
77+
- on_payload (vk): 7
78+
- on_commands: 6
79+
- on_attachments: 3
80+
- on_any_unprocessed_message: -3
81+
- Rest: ~0
82+
7283
Attachments
7384
^^^^^^^^^^^
7485

‎kutana/kutana.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def _init_routers(self):
120120

121121
def _add_router(new_router):
122122
for router in self._routers:
123-
if isinstance(router, new_router.__class__):
123+
if type(router) is type(new_router) and router.priority == new_router.priority:
124124
router.merge(new_router)
125125
return
126126

‎kutana/router.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ def _key(self, handler):
1616
-handler.priority,
1717
)
1818

19+
def _assert_routers_alike(self, other_router):
20+
if type(other_router) is not type(self):
21+
raise RuntimeError("Can't merge routers with different classes")
22+
23+
if other_router.priority != self.priority:
24+
raise RuntimeError("Can't merge routers with different priorities")
25+
1926
def _check_update(self, update, ctx):
2027
"""Should update be processed?"""
2128
return True
@@ -46,9 +53,7 @@ def add_handler(self, handler):
4653
self._handlers.add(handler)
4754

4855
def merge(self, other_router):
49-
if not isinstance(other_router, self.__class__):
50-
raise RuntimeError("Can't merge routers with different classes")
51-
56+
self._assert_routers_alike(other_router)
5257
self._handlers.update(other_router._handlers)
5358

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

8792
def merge(self, other_router):
88-
if not isinstance(other_router, self.__class__):
89-
raise RuntimeError("Can't merge routers with different classes")
93+
self._assert_routers_alike(other_router)
9094

9195
for key, handlers in other_router._handlers.items():
9296
for handler in handlers:

‎setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import setuptools
99

1010

11-
VERSION = "4.1.5"
11+
VERSION = "4.1.6"
1212

1313

1414
with open("README.md", "r") as fh:

‎tests/test_router.py

+64
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from kutana import Context
33
from kutana.handler import Handler
44
from kutana.router import Router, ListRouter, MapRouter
5+
from kutana.routers import AnyMessageRouter, AnyUnprocessedMessageRouter
56

67

78
def test_check():
@@ -52,3 +53,66 @@ def test_router_merge():
5253

5354
assert len(mr1._handlers["a"]) == 2
5455
assert len(mr1._handlers["b"]) == 1
56+
57+
58+
def test_router_subclass_merge():
59+
mr1 = AnyMessageRouter()
60+
mr2 = AnyUnprocessedMessageRouter()
61+
mr3 = ListRouter()
62+
mr4 = AnyMessageRouter()
63+
64+
mr1.add_handler(Handler(1, "*", "*", 0))
65+
mr1.add_handler(Handler(2, "*", "*", 0))
66+
mr2.add_handler(Handler(3, "*", "*", 0))
67+
mr3.add_handler(Handler(4, "*", "*", 0))
68+
mr4.add_handler(Handler(5, "*", "*", 0))
69+
70+
with pytest.raises(RuntimeError):
71+
mr1.merge(mr2)
72+
73+
with pytest.raises(RuntimeError):
74+
mr1.merge(mr3)
75+
76+
with pytest.raises(RuntimeError):
77+
mr2.merge(mr3)
78+
79+
mr4.merge(mr1)
80+
81+
assert len(mr1._handlers) == 2
82+
assert len(mr2._handlers) == 1
83+
assert len(mr3._handlers) == 1
84+
assert len(mr4._handlers) == 3
85+
assert set(map(lambda h: h.handle, mr4._handlers)) == {5, 1, 2}
86+
87+
88+
def test_router_merge_priority():
89+
mr1 = AnyMessageRouter(priority=9)
90+
mr2 = AnyMessageRouter(priority=7)
91+
mr3 = AnyMessageRouter(priority=5)
92+
mr4 = AnyMessageRouter(priority=5)
93+
94+
mr1.add_handler(Handler(1, "*", "*", 0))
95+
mr2.add_handler(Handler(2, "*", "*", 0))
96+
mr3.add_handler(Handler(3, "*", "*", 0))
97+
mr3.add_handler(Handler(4, "*", "*", 5))
98+
mr4.add_handler(Handler(5, "*", "*", 3))
99+
mr4.add_handler(Handler(6, "*", "*", 10))
100+
101+
with pytest.raises(RuntimeError):
102+
mr1.merge(mr2)
103+
104+
with pytest.raises(RuntimeError):
105+
mr1.merge(mr3)
106+
107+
with pytest.raises(RuntimeError):
108+
mr2.merge(mr3)
109+
110+
mr3.merge(mr4)
111+
112+
handlers = list(map(lambda h: h.handle, [
113+
*mr1._handlers,
114+
*mr2._handlers,
115+
*mr3._handlers,
116+
]))
117+
118+
assert handlers == [1, 2, 6, 4, 5, 3]

0 commit comments

Comments
 (0)
Please sign in to comment.