88
99from __future__ import print_function
1010
11+ from contextlib import contextmanager
1112from functools import partial
1213import sys
1314
@@ -251,17 +252,25 @@ class SequenceDispatcher(object):
251252 runs ``func`` to perform intents in strict sequence.
252253
253254 So, if you expect to first perform an intent like ``MyIntent('a')`` and
254- then an intent like ``OtherIntent('b')``, you can create a dispatcher like
255- this::
255+ then an intent like ``OtherIntent('b')``, you can create and use a
256+ dispatcher like this::
256257
257- SequenceDispatcher([
258+ sequence = SequenceDispatcher([
258259 (MyIntent('a'), lambda i: 'my-intent-result'),
259260 (OtherIntent('b'), lambda i: 'other-intent-result')
260261 ])
261262
263+ with sequence.consume():
264+ perform(sequence, eff)
265+
266+ It's important to use `with sequence.consume():` to ensure that all of the
267+ intents are performed. Otherwise, if your code has a bug that causes it to
268+ return before all effects are performed, your test may not fail.
269+
262270 :obj:`None` is returned if the next intent in the sequence is not equal to
263271 the intent being performed, or if there are no more items left in the
264- sequence.
272+ sequence (this is standard behavior for dispatchers that don't handle an
273+ intent).
265274 """
266275 def __init__ (self , sequence ):
267276 """:param list sequence: Sequence of (intent, fn)."""
@@ -274,3 +283,19 @@ def __call__(self, intent):
274283 if intent == exp_intent :
275284 self .sequence = self .sequence [1 :]
276285 return sync_performer (lambda d , i : func (i ))
286+
287+ def consumed (self ):
288+ """Return True if all of the steps were performed."""
289+ return len (self .sequence ) == 0
290+
291+ @contextmanager
292+ def consume (self ):
293+ """
294+ Return a context manager that can be used with the `with` syntax to
295+ ensure that all steps are performed by the end.
296+ """
297+ yield
298+ if not self .consumed ():
299+ raise AssertionError (
300+ "Not all intents were performed: {0}" .format (
301+ [x [0 ] for x in self .sequence ]))
0 commit comments