Skip to content

Commit b52277e

Browse files
committed
add EQFDispatcher
1 parent 3fd2c6d commit b52277e

2 files changed

Lines changed: 51 additions & 6 deletions

File tree

effect/test_testing.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
ESError,
1818
ESFunc,
1919
EQDispatcher,
20+
EQFDispatcher,
2021
fail_effect,
2122
resolve_effect,
2223
resolve_stubs)
@@ -255,11 +256,23 @@ class EQDispatcherTests(TestCase):
255256
def test_no_intent(self):
256257
"""When the dispatcher can't match the intent, it returns None."""
257258
d = EQDispatcher({})
258-
self.assertIs(d("foo"), None)
259+
self.assertIs(d('foo'), None)
259260

260261
def test_perform(self):
261262
"""When an intent matches, performing it returns the canned result."""
262-
d = EQDispatcher({"hello": "there"})
263-
self.assertEqual(
264-
sync_perform(d, Effect("hello")),
265-
"there")
263+
d = EQDispatcher({'hello': 'there'})
264+
self.assertEqual(sync_perform(d, Effect('hello')), 'there')
265+
266+
267+
class EQFDispatcherTests(TestCase):
268+
"""Tests for :obj:`EQFDispatcher`."""
269+
270+
def test_no_intent(self):
271+
"""When the dispatcher can't match the intent, it returns None."""
272+
d = EQFDispatcher({})
273+
self.assertIs(d('foo'), None)
274+
275+
def test_perform(self):
276+
"""When an intent matches, performing it returns the canned result."""
277+
d = EQFDispatcher({'hello': lambda i: (i, 'there')})
278+
self.assertEqual(sync_perform(d, Effect('hello')), ('hello', 'there'))

effect/testing.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ class EQDispatcher(object):
178178
e.g.::
179179
180180
>>> sync_perform(EQDispatcher({MyIntent(1, 2): 'the-result'}),
181-
Effect(MyIntent(1, 2)))
181+
... Effect(MyIntent(1, 2)))
182182
'the-result'
183183
184184
assuming MyIntent supports ``__eq__`` by value.
@@ -194,3 +194,35 @@ def __call__(self, intent):
194194
for k, v in self.mapping.items():
195195
if k == intent:
196196
return sync_performer(lambda d, i: v)
197+
198+
199+
class EQFDispatcher(object):
200+
"""
201+
A dispatcher that looks up intents by equality and performs them by
202+
invoking a provided function.
203+
204+
Users provide a mapping of intents to functions, where the intents are
205+
matched against the intents being performed with a simple equality check
206+
(not a type check!).
207+
208+
e.g.::
209+
210+
>>> sync_perform(
211+
... EQFDispatcher({
212+
... MyIntent(1, 2): lambda i: 'the-result'}),
213+
... Effect(MyIntent(1, 2)))
214+
'the-result'
215+
216+
assuming MyIntent supports ``__eq__`` by value.
217+
"""
218+
def __init__(self, mapping):
219+
"""
220+
:param mapping: Mapping of intents to results.
221+
"""
222+
self.mapping = mapping
223+
224+
def __call__(self, intent):
225+
# Avoid hashing, because a lot of intents aren't hashable.
226+
for k, v in self.mapping.items():
227+
if k == intent:
228+
return sync_performer(lambda d, i: v(i))

0 commit comments

Comments
 (0)