-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_dispatch.py
More file actions
77 lines (51 loc) · 1.99 KB
/
Copy pathtest_dispatch.py
File metadata and controls
77 lines (51 loc) · 1.99 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
"""Behavioral tests for the Operation building block."""
from __future__ import annotations
from dataclasses import dataclass
import pytest
from patterns.behavioral.visitor import Operation, UnhandledNodeError
@dataclass(frozen=True)
class Circle:
radius: float
@dataclass(frozen=True)
class Square:
side: float
class TestDispatch:
def test_calls_dispatch_on_the_nodes_type(self) -> None:
area: Operation[float] = Operation("area")
@area.register
def _(node: Circle) -> float:
return 3.14159 * node.radius**2
@area.register
def _(node: Square) -> float:
return node.side**2
assert area(Square(3.0)) == 9.0
assert area(Circle(1.0)) == pytest.approx(3.14159)
def test_register_hands_the_case_back_usable(self) -> None:
name: Operation[str] = Operation("name")
@name.register
def circle_name(node: Circle) -> str:
return "circle"
assert circle_name(Circle(1.0)) == "circle"
def test_registered_types_reports_the_handled_family(self) -> None:
op: Operation[str] = Operation("op")
@op.register
def _(node: Circle) -> str:
return "c"
assert op.registered_types() == frozenset({Circle})
class TestStrictDefault:
def test_unregistered_type_raises_naming_operation_and_handled_types(self) -> None:
area: Operation[float] = Operation("area")
@area.register
def _(node: Circle) -> float:
return 0.0
with pytest.raises(UnhandledNodeError, match=r"'area' has no case for Square.*Circle"):
area(Square(2.0))
def test_operations_are_independent_families(self) -> None:
first: Operation[int] = Operation("first")
second: Operation[int] = Operation("second")
@first.register
def _(node: Circle) -> int:
return 1
assert first(Circle(1.0)) == 1
with pytest.raises(UnhandledNodeError):
second(Circle(1.0))