11
22import operator
33
4- from effect import ComposedDispatcher , Effect , base_dispatcher , sync_perform
5- from effect .fold import fold_effect
4+ from pytest import raises
5+
6+ from effect import (
7+ ComposedDispatcher , Effect , Error ,
8+ base_dispatcher , sync_perform )
9+ from effect .fold import FoldError , fold_effect
610from effect .testing import SequenceDispatcher
711
812
13+ def _disp (dispatcher ):
14+ return ComposedDispatcher ([dispatcher , base_dispatcher ])
15+
16+
917def test_fold_effect ():
1018 """Behaves like foldM."""
1119 effs = [Effect ('a' ), Effect ('b' ), Effect ('c' )]
@@ -18,9 +26,7 @@ def test_fold_effect():
1826 eff = fold_effect (operator .add , 'Nil' , effs )
1927
2028 with dispatcher .consume ():
21- result = sync_perform (
22- ComposedDispatcher ([dispatcher , base_dispatcher ]),
23- eff )
29+ result = sync_perform (_disp (dispatcher ), eff )
2430 assert result == 'NilEiBeeCee'
2531
2632
@@ -31,3 +37,24 @@ def test_fold_effect_empty():
3137 eff = fold_effect (operator .add , 0 , [])
3238 result = sync_perform (base_dispatcher , eff )
3339 assert result == 0
40+
41+
42+ def test_fold_effect_errors ():
43+ """
44+ When one of the effects in the folding list fails, a FoldError is raised
45+ with the accumulator so far.
46+ """
47+ effs = [Effect ('a' ), Effect (Error (ZeroDivisionError ('foo' ))), Effect ('c' )]
48+
49+ dispatcher = SequenceDispatcher ([
50+ ('a' , lambda i : 'Ei' ),
51+ ])
52+
53+ eff = fold_effect (operator .add , 'Nil' , effs )
54+
55+ with dispatcher .consume ():
56+ with raises (FoldError ) as excinfo :
57+ sync_perform (_disp (dispatcher ), eff )
58+ assert excinfo .value .accumulator == 'NilEi'
59+ assert excinfo .value .wrapped_exception [0 ] is ZeroDivisionError
60+ assert str (excinfo .value .wrapped_exception [1 ]) == 'foo'
0 commit comments