-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathtest_fold.py
More file actions
106 lines (81 loc) · 3.09 KB
/
Copy pathtest_fold.py
File metadata and controls
106 lines (81 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import operator
from pytest import raises
from testtools.assertions import assert_that
from effect import Effect, Error, base_dispatcher, sync_perform
from effect.fold import FoldError, fold_effect, sequence
from effect.testing import perform_sequence
from ._test_utils import MatchesException
def test_fold_effect():
"""
:func:`fold_effect` folds the given function over the results of the
effects.
"""
effs = [Effect("a"), Effect("b"), Effect("c")]
dispatcher = [
("a", lambda i: "Ei"),
("b", lambda i: "Bee"),
("c", lambda i: "Cee"),
]
eff = fold_effect(operator.add, "Nil", effs)
result = perform_sequence(dispatcher, eff)
assert result == "NilEiBeeCee"
def test_fold_effect_empty():
"""
Returns an Effect resulting in the initial value when there are no effects.
"""
eff = fold_effect(operator.add, 0, [])
result = sync_perform(base_dispatcher, eff)
assert result == 0
def test_fold_effect_errors():
"""
When one of the effects in the folding list fails, a FoldError is raised
with the accumulator so far.
"""
effs = [Effect("a"), Effect(Error(ZeroDivisionError("foo"))), Effect("c")]
dispatcher = [("a", lambda i: "Ei")]
eff = fold_effect(operator.add, "Nil", effs)
with raises(FoldError) as excinfo:
perform_sequence(dispatcher, eff)
assert excinfo.value.accumulator == "NilEi"
assert_that(
excinfo.value.wrapped_exception, MatchesException(ZeroDivisionError("foo"))
)
def test_fold_effect_str():
"""str()ing a FoldError returns useful traceback/exception info."""
effs = [Effect("a"), Effect(Error(ZeroDivisionError("foo"))), Effect("c")]
dispatcher = [("a", lambda i: "Ei")]
eff = fold_effect(operator.add, "Nil", effs)
with raises(FoldError) as excinfo:
perform_sequence(dispatcher, eff)
assert str(excinfo.value).startswith(
"<FoldError after accumulating 'NilEi'> Original traceback follows:\n"
)
assert str(excinfo.value).endswith("ZeroDivisionError: foo")
def test_sequence():
"""Collects each Effectful result into a list."""
effs = [Effect("a"), Effect("b"), Effect("c")]
dispatcher = [
("a", lambda i: "Ei"),
("b", lambda i: "Bee"),
("c", lambda i: "Cee"),
]
eff = sequence(effs)
result = perform_sequence(dispatcher, eff)
assert result == ["Ei", "Bee", "Cee"]
def test_sequence_empty():
"""Returns an empty list when there are no Effects."""
assert sync_perform(base_dispatcher, sequence([])) == []
def test_sequence_error():
"""
Allows :obj:`FoldError` to be raised when an Effect fails. The list
accumulated so far is the `accumulator` value in the :obj:`FoldError`.
"""
effs = [Effect("a"), Effect(Error(ZeroDivisionError("foo"))), Effect("c")]
dispatcher = [("a", lambda i: "Ei")]
eff = sequence(effs)
with raises(FoldError) as excinfo:
perform_sequence(dispatcher, eff)
assert excinfo.value.accumulator == ["Ei"]
assert_that(
excinfo.value.wrapped_exception, MatchesException(ZeroDivisionError("foo"))
)