|
7 | 7 | Theme: War of the Ring — multiple simultaneous fronts. |
8 | 8 | """ |
9 | 9 |
|
| 10 | +from enum import Enum |
| 11 | +from enum import auto |
| 12 | + |
10 | 13 | import pytest |
| 14 | +from statemachine.states import States |
11 | 15 |
|
| 16 | +from statemachine import State |
| 17 | +from statemachine import StateChart |
12 | 18 | from tests.machines.parallel.session import Session |
13 | 19 | from tests.machines.parallel.session_with_done_state import SessionWithDoneState |
14 | 20 | from tests.machines.parallel.two_towers import TwoTowers |
@@ -139,6 +145,53 @@ async def test_top_level_parallel_done_state_fires_before_termination(self, sm_r |
139 | 145 | assert {"finished"} == set(sm.configuration_values) |
140 | 146 | assert sm.is_terminated is True |
141 | 147 |
|
| 148 | + async def test_from_enum_inside_parallel(self, sm_runner): |
| 149 | + """States.from_enum() works inside parallel states (#606).""" |
| 150 | + |
| 151 | + class RegionA(Enum): |
| 152 | + IDLE = auto() |
| 153 | + ACTIVE = auto() |
| 154 | + |
| 155 | + class RegionB(Enum): |
| 156 | + OFF = auto() |
| 157 | + ON = auto() |
| 158 | + |
| 159 | + class SC(StateChart): |
| 160 | + start = State(initial=True) |
| 161 | + done = State(final=True) |
| 162 | + |
| 163 | + class work(State.Parallel): |
| 164 | + class region_a(State.Compound): |
| 165 | + a = States.from_enum(RegionA, initial=RegionA.IDLE, final=RegionA.ACTIVE) |
| 166 | + go_a = a.IDLE.to(a.ACTIVE) |
| 167 | + |
| 168 | + class region_b(State.Compound): |
| 169 | + b = States.from_enum(RegionB, initial=RegionB.OFF, final=RegionB.ON) |
| 170 | + go_b = b.OFF.to(b.ON) |
| 171 | + |
| 172 | + begin = start.to(work) |
| 173 | + finish = work.to(done) |
| 174 | + |
| 175 | + sm = await sm_runner.start(SC) |
| 176 | + assert {"start"} == set(sm.configuration_values) |
| 177 | + |
| 178 | + await sm_runner.send(sm, "begin") |
| 179 | + vals = set(sm.configuration_values) |
| 180 | + assert "work" in vals |
| 181 | + assert RegionA.IDLE in vals |
| 182 | + assert RegionB.OFF in vals |
| 183 | + |
| 184 | + await sm_runner.send(sm, "go_a") |
| 185 | + vals = set(sm.configuration_values) |
| 186 | + assert RegionA.ACTIVE in vals |
| 187 | + assert RegionB.OFF in vals # region_b unchanged |
| 188 | + |
| 189 | + await sm_runner.send(sm, "go_b") |
| 190 | + # Both regions final -> done.state.work fires |
| 191 | + assert {RegionA.ACTIVE, RegionB.ON} <= set(sm.configuration_values) or {"done"} == set( |
| 192 | + sm.configuration_values |
| 193 | + ) |
| 194 | + |
142 | 195 | async def test_top_level_parallel_not_terminated_when_one_region_pending(self, sm_runner): |
143 | 196 | """Machine keeps running when only one region reaches final.""" |
144 | 197 | sm = await sm_runner.start(Session) |
|
0 commit comments