-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_skeleton.py
More file actions
78 lines (58 loc) · 2.82 KB
/
Copy pathtest_skeleton.py
File metadata and controls
78 lines (58 loc) · 2.82 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
"""Behavioral tests for the Skeleton building block."""
from __future__ import annotations
from patterns.behavioral.template_method import Skeleton, discard, keep_all
def recording_skeleton(trace: list[str]) -> Skeleton[str, str]:
def fetch() -> str:
trace.append("fetch")
return "raw"
def transform(data: str) -> str:
trace.append("transform")
return f"{data}+clean"
def render(data: str) -> str:
trace.append("render")
return f"[{data}]"
def deliver(document: str) -> None:
trace.append(f"deliver:{document}")
return Skeleton(fetch=fetch, transform=transform, render=render, deliver=deliver)
class TestSpine:
def test_run_executes_the_four_steps_in_fixed_order(self) -> None:
trace: list[str] = []
result = recording_skeleton(trace).run()
assert result == "[raw+clean]"
assert trace == ["fetch", "transform", "render", "deliver:[raw+clean]"]
def test_the_delivered_document_is_the_rendered_one(self) -> None:
trace: list[str] = []
recording_skeleton(trace).run()
assert trace[-1] == "deliver:[raw+clean]"
class TestVariation:
def test_with_steps_swaps_one_step_and_keeps_the_rest(self) -> None:
trace: list[str] = []
variant = recording_skeleton(trace).with_steps(render=lambda data: data.upper())
assert variant.run() == "RAW+CLEAN"
assert "fetch" in trace # untouched steps still ran
def test_with_steps_returns_a_new_skeleton_leaving_the_original_alone(self) -> None:
trace: list[str] = []
base = recording_skeleton(trace)
base.with_steps(render=lambda data: "other")
assert base.run() == "[raw+clean]" # original unchanged
def test_every_step_is_individually_swappable(self) -> None:
trace: list[str] = []
base = recording_skeleton(trace)
assert base.with_steps(fetch=lambda: "other").run() == "[other+clean]"
assert base.with_steps(transform=lambda data: data).run() == "[raw]"
assert base.with_steps(render=lambda data: data.upper()).run() == "RAW+CLEAN"
delivered: list[str] = []
base.with_steps(deliver=delivered.append).run()
assert delivered == ["[raw+clean]"]
class TestExplicitNoOps:
def test_keep_all_is_the_identity_transform(self) -> None:
assert keep_all((1, 2)) == (1, 2)
def test_discard_delivers_nowhere(self) -> None:
# Prove nothing is delivered: a skeleton whose only sink is a
# recording list, with discard swapped in, records nothing.
delivered: list[str] = []
trace: list[str] = []
base = recording_skeleton(trace).with_steps(deliver=delivered.append)
base.with_steps(deliver=discard).run()
assert delivered == []
assert base.run() == "[raw+clean]" and delivered == ["[raw+clean]"]