Skip to content

Commit 11ffa95

Browse files
authored
refactor: extract test StateChart definitions to tests/machines/ (#591)
Move reusable StateChart class definitions from inline test code to dedicated modules under tests/machines/, organized by feature: - workflow/: CampaignMachine variants, ReverseTrafficLightMachine - error/: ErrorInGuardSC, ErrorInActionSC, ErrorInErrorHandlerSC, etc. - validators/: OrderValidation, MultiValidator, ValidatorWithCond, etc. - compound/: ShireToRivendell, MoriaExpedition, MiddleEarthJourney, etc. - history/: GollumPersonality variants, DeepMemoryOfMoria, ShallowMoria - parallel/: WarOfTheRing, TwoTowers, Session variants - eventless/: RingCorruption variants, BeaconChain, AutoAdvance, etc. - in_condition/: Fellowship, GateOfMoria, CombinedGuard, etc. - donedata/: DestroyTheRing, NestedQuestDoneData, QuestForErebor variants Test files now import from these modules instead of defining classes inline. Machines that test invalid definitions or use closures remain inline in test files.
1 parent 966500d commit 11ffa95

75 files changed

Lines changed: 1067 additions & 1020 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

tests/conftest.py

Lines changed: 9 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -22,86 +22,32 @@ def current_time():
2222

2323
@pytest.fixture()
2424
def campaign_machine():
25-
"Define a new class for each test"
26-
from statemachine import State
27-
from statemachine import StateChart
28-
29-
class CampaignMachine(StateChart):
30-
"A workflow machine"
31-
32-
draft = State(initial=True)
33-
producing = State("Being produced")
34-
closed = State(final=True)
35-
36-
add_job = draft.to(draft) | producing.to(producing)
37-
produce = draft.to(producing)
38-
deliver = producing.to(closed)
25+
from tests.machines.workflow.campaign_machine import CampaignMachine
3926

4027
return CampaignMachine
4128

4229

4330
@pytest.fixture()
4431
def campaign_machine_with_validator():
45-
"Define a new class for each test"
46-
from statemachine import State
47-
from statemachine import StateChart
48-
49-
class CampaignMachine(StateChart):
50-
"A workflow machine"
51-
52-
draft = State(initial=True)
53-
producing = State("Being produced")
54-
closed = State(final=True)
55-
56-
add_job = draft.to(draft) | producing.to(producing)
57-
produce = draft.to(producing, validators="can_produce")
58-
deliver = producing.to(closed)
32+
from tests.machines.workflow.campaign_machine_with_validator import (
33+
CampaignMachineWithValidator,
34+
)
5935

60-
def can_produce(*args, **kwargs):
61-
if "goods" not in kwargs:
62-
raise LookupError("Goods not found.")
63-
64-
return CampaignMachine
36+
return CampaignMachineWithValidator
6537

6638

6739
@pytest.fixture()
6840
def campaign_machine_with_final_state():
69-
"Define a new class for each test"
70-
from statemachine import State
71-
from statemachine import StateChart
72-
73-
class CampaignMachine(StateChart):
74-
"A workflow machine"
75-
76-
draft = State(initial=True)
77-
producing = State("Being produced")
78-
closed = State(final=True)
79-
80-
add_job = draft.to(draft) | producing.to(producing)
81-
produce = draft.to(producing)
82-
deliver = producing.to(closed)
41+
from tests.machines.workflow.campaign_machine import CampaignMachine
8342

8443
return CampaignMachine
8544

8645

8746
@pytest.fixture()
8847
def campaign_machine_with_values():
89-
"Define a new class for each test"
90-
from statemachine import State
91-
from statemachine import StateChart
92-
93-
class CampaignMachineWithKeys(StateChart):
94-
"A workflow machine"
95-
96-
draft = State(initial=True, value=1)
97-
producing = State("Being produced", value=2)
98-
closed = State(value=3, final=True)
99-
100-
add_job = draft.to(draft) | producing.to(producing)
101-
produce = draft.to(producing)
102-
deliver = producing.to(closed)
48+
from tests.machines.workflow.campaign_machine_with_values import CampaignMachineWithValues
10349

104-
return CampaignMachineWithKeys
50+
return CampaignMachineWithValues
10551

10652

10753
@pytest.fixture()
@@ -153,18 +99,7 @@ def classic_traffic_light_machine_allow_event(classic_traffic_light_machine):
15399

154100
@pytest.fixture()
155101
def reverse_traffic_light_machine():
156-
from statemachine import State
157-
from statemachine import StateChart
158-
159-
class ReverseTrafficLightMachine(StateChart):
160-
"A traffic light machine"
161-
162-
green = State(initial=True)
163-
yellow = State()
164-
red = State()
165-
166-
stop = red.from_(yellow, green, red)
167-
cycle = green.from_(red) | yellow.from_(green) | red.from_(yellow) | red.from_.itself()
102+
from tests.machines.workflow.reverse_traffic_light import ReverseTrafficLightMachine
168103

169104
return ReverseTrafficLightMachine
170105

tests/machines/compound/__init__.py

Whitespace-only changes.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from statemachine import State
2+
from statemachine import StateChart
3+
4+
5+
class MiddleEarthJourney(StateChart):
6+
class rivendell(State.Compound):
7+
council = State(initial=True)
8+
preparing = State()
9+
10+
get_ready = council.to(preparing)
11+
12+
class moria(State.Compound):
13+
gates = State(initial=True)
14+
bridge = State(final=True)
15+
16+
cross = gates.to(bridge)
17+
18+
class lothlorien(State.Compound):
19+
mirror = State(initial=True)
20+
departure = State(final=True)
21+
22+
leave = mirror.to(departure)
23+
24+
march_to_moria = rivendell.to(moria)
25+
march_to_lorien = moria.to(lothlorien)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from statemachine import State
2+
from statemachine import StateChart
3+
4+
5+
class MiddleEarthJourneyTwoCompounds(StateChart):
6+
class rivendell(State.Compound):
7+
council = State(initial=True)
8+
preparing = State()
9+
10+
get_ready = council.to(preparing)
11+
12+
class moria(State.Compound):
13+
gates = State(initial=True)
14+
bridge = State(final=True)
15+
16+
cross = gates.to(bridge)
17+
18+
march_to_moria = rivendell.to(moria)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from statemachine import State
2+
from statemachine import StateChart
3+
4+
5+
class MiddleEarthJourneyWithFinals(StateChart):
6+
class rivendell(State.Compound):
7+
council = State(initial=True)
8+
preparing = State(final=True)
9+
10+
get_ready = council.to(preparing)
11+
12+
class moria(State.Compound):
13+
gates = State(initial=True)
14+
bridge = State(final=True)
15+
16+
cross = gates.to(bridge)
17+
18+
class lothlorien(State.Compound):
19+
mirror = State(initial=True)
20+
departure = State(final=True)
21+
22+
leave = mirror.to(departure)
23+
24+
march_to_moria = rivendell.to(moria)
25+
march_to_lorien = moria.to(lothlorien)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from statemachine import State
2+
from statemachine import StateChart
3+
4+
5+
class MoriaExpedition(StateChart):
6+
class moria(State.Compound):
7+
class upper_halls(State.Compound):
8+
entrance = State(initial=True)
9+
bridge = State(final=True)
10+
11+
cross = entrance.to(bridge)
12+
13+
assert isinstance(upper_halls, State)
14+
depths = State(final=True)
15+
descend = upper_halls.to(depths)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from statemachine import State
2+
from statemachine import StateChart
3+
4+
5+
class MoriaExpeditionWithEscape(StateChart):
6+
class moria(State.Compound):
7+
class upper_halls(State.Compound):
8+
entrance = State(initial=True)
9+
bridge = State()
10+
11+
cross = entrance.to(bridge)
12+
13+
assert isinstance(upper_halls, State)
14+
depths = State(final=True)
15+
descend = upper_halls.to(depths)
16+
17+
daylight = State(final=True)
18+
escape = moria.to(daylight)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from statemachine import State
2+
from statemachine import StateChart
3+
4+
5+
class QuestForErebor(StateChart):
6+
class lonely_mountain(State.Compound):
7+
approach = State(initial=True)
8+
inside = State(final=True)
9+
10+
enter_mountain = approach.to(inside)
11+
12+
victory = State(final=True)
13+
done_state_lonely_mountain = lonely_mountain.to(victory)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from statemachine import State
2+
from statemachine import StateChart
3+
4+
5+
class ShireToRivendell(StateChart):
6+
class shire(State.Compound):
7+
bag_end = State(initial=True)
8+
green_dragon = State()
9+
10+
visit_pub = bag_end.to(green_dragon)
11+
12+
road = State(final=True)
13+
depart = shire.to(road)

tests/machines/donedata/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)