1111from redux .basic_types import (
1212 AutorunOptions ,
1313 BaseAction ,
14+ BaseEvent ,
1415 CompleteReducerResult ,
1516 CreateStoreOptions ,
1617 FinishAction ,
2223from redux .main import Store
2324
2425if TYPE_CHECKING :
25- from collections .abc import Callable , Coroutine
26+ from collections .abc import Generator
2627
2728 from redux_pytest .fixtures .event_loop import LoopThread
2829
@@ -37,21 +38,28 @@ class StateType(Immutable):
3738class IncrementAction (BaseAction ): ...
3839
3940
41+ class IncrementEvent (BaseEvent ):
42+ post_value : int
43+
44+
4045class SetMirroredValueAction (BaseAction ):
4146 value : int
4247
4348
4449def reducer (
4550 state : StateType | None ,
4651 action : Action ,
47- ) -> StateType | CompleteReducerResult [StateType , Action , FinishEvent ]:
52+ ) -> StateType | CompleteReducerResult [StateType , Action , IncrementEvent ]:
4853 if state is None :
4954 if isinstance (action , InitAction ):
5055 return StateType (value = 0 , mirrored_value = 0 )
5156 raise InitializationActionError (action )
5257
5358 if isinstance (action , IncrementAction ):
54- return replace (state , value = state .value + 1 )
59+ return CompleteReducerResult (
60+ state = replace (state , value = state .value + 1 ),
61+ events = [IncrementEvent (post_value = state .value + 1 )],
62+ )
5563 if isinstance (action , SetMirroredValueAction ):
5664 return replace (state , mirrored_value = action .value )
5765 return state
@@ -62,25 +70,16 @@ def reducer(
6270
6371
6472@pytest .fixture
65- def store (event_loop : LoopThread ) -> StoreType :
66- def _create_task_with_callback (
67- coro : Coroutine ,
68- callback : Callable [[asyncio .Task ], None ] | None = None ,
69- ) -> None :
70- def create_task_with_callback () -> None :
71- task = event_loop .loop .create_task (coro )
72- if callback :
73- callback (task )
74-
75- event_loop .loop .call_soon_threadsafe (create_task_with_callback )
76-
77- return Store (
73+ def store (event_loop : LoopThread ) -> Generator [StoreType , None , None ]:
74+ store = Store (
7875 reducer ,
7976 options = CreateStoreOptions (
8077 auto_init = True ,
81- task_creator = _create_task_with_callback ,
78+ task_creator = event_loop . create_task ,
8279 ),
8380 )
81+ yield store
82+ store .subscribe_event (FinishEvent , lambda : event_loop .stop ())
8483
8584
8685def dispatch_actions (store : StoreType ) -> None :
@@ -90,7 +89,6 @@ def dispatch_actions(store: StoreType) -> None:
9089
9190def test_autorun (
9291 store : StoreType ,
93- event_loop : LoopThread ,
9492) -> None :
9593 @store .autorun (lambda state : state .value )
9694 async def sync_mirror (value : int ) -> int :
@@ -107,16 +105,12 @@ async def sync_mirror(value: int) -> int:
107105 def _ (mirrored_value : int ) -> None :
108106 if mirrored_value < INCREMENTS :
109107 return
110- event_loop .stop ()
111108 store .dispatch (FinishAction ())
112109
113110 dispatch_actions (store )
114111
115112
116- def test_autorun_autoawait (
117- store : StoreType ,
118- event_loop : LoopThread ,
119- ) -> None :
113+ def test_autorun_autoawait (store : StoreType ) -> None :
120114 @store .autorun (lambda state : state .value , options = AutorunOptions (auto_await = False ))
121115 async def sync_mirror (value : int ) -> int :
122116 store .dispatch (SetMirroredValueAction (value = value ))
@@ -139,14 +133,10 @@ async def _(values: tuple[int, int]) -> None:
139133 elif value < INCREMENTS :
140134 store .dispatch (IncrementAction ())
141135 else :
142- event_loop .stop ()
143136 store .dispatch (FinishAction ())
144137
145138
146- def test_autorun_default_value (
147- store : StoreType ,
148- event_loop : LoopThread ,
149- ) -> None :
139+ def test_autorun_default_value (store : StoreType ) -> None :
150140 @store .autorun (lambda state : state .value , options = AutorunOptions (default_value = 5 ))
151141 async def _ (value : int ) -> int :
152142 store .dispatch (SetMirroredValueAction (value = value ))
@@ -156,19 +146,16 @@ async def _(value: int) -> int:
156146 lambda state : state .mirrored_value ,
157147 lambda state : state .mirrored_value >= INCREMENTS ,
158148 )
159- def _ (mirrored_value : int ) -> None :
149+ async def _ (mirrored_value : int ) -> None :
160150 if mirrored_value < INCREMENTS :
161151 return
162- event_loop . stop ( )
152+ await asyncio . sleep ( 0.1 )
163153 store .dispatch (FinishAction ())
164154
165155 dispatch_actions (store )
166156
167157
168- def test_view (
169- store : StoreType ,
170- event_loop : LoopThread ,
171- ) -> None :
158+ def test_view (store : StoreType ) -> None :
172159 calls = []
173160
174161 @store .view (lambda state : state .value )
@@ -184,12 +171,11 @@ async def _(value: int) -> None:
184171 if value < INCREMENTS :
185172 store .dispatch (IncrementAction ())
186173 else :
187- event_loop .stop ()
188174 store .dispatch (FinishAction ())
189175 assert calls == list (range (INCREMENTS + 1 ))
190176
191177
192- def test_view_await (store : StoreType , event_loop : LoopThread ) -> None :
178+ def test_view_await (store : StoreType ) -> None :
193179 calls = []
194180
195181 @store .view (lambda state : state .value )
@@ -208,15 +194,11 @@ async def _(value: int) -> None:
208194 if value < INCREMENTS :
209195 store .dispatch (IncrementAction ())
210196 else :
211- event_loop .stop ()
212197 store .dispatch (FinishAction ())
213198 assert calls == list (range (INCREMENTS + 1 ))
214199
215200
216- def test_view_with_args (
217- store : StoreType ,
218- event_loop : LoopThread ,
219- ) -> None :
201+ def test_view_with_args (store : StoreType ) -> None :
220202 calls = []
221203
222204 @store .view (lambda state : state .value )
@@ -231,15 +213,11 @@ async def _(value: int) -> None:
231213 if value < INCREMENTS :
232214 store .dispatch (IncrementAction ())
233215 else :
234- event_loop .stop ()
235216 store .dispatch (FinishAction ())
236217 assert calls == [j for i in list (range (INCREMENTS + 1 )) for j in [i ] * 2 ]
237218
238219
239- def test_view_with_default_value (
240- store : StoreType ,
241- event_loop : LoopThread ,
242- ) -> None :
220+ def test_view_with_default_value (store : StoreType ) -> None :
243221 calls = []
244222
245223 @store .view (lambda state : state .value , options = ViewOptions (default_value = 5 ))
@@ -253,51 +231,39 @@ async def _(value: int) -> None:
253231 if value < INCREMENTS :
254232 store .dispatch (IncrementAction ())
255233 else :
256- event_loop .stop ()
257234 store .dispatch (FinishAction ())
258235 assert calls == list (range (INCREMENTS + 1 ))
259236
260237 store .dispatch (InitAction ())
261238
262239
263- def test_subscription (
264- store : StoreType ,
265- event_loop : LoopThread ,
266- ) -> None :
240+ def test_subscription (store : StoreType ) -> None :
267241 async def render (state : StateType ) -> None :
242+ await asyncio .sleep (0.1 )
268243 if state .value == INCREMENTS :
269244 unsubscribe ()
270245 store .dispatch (FinishAction ())
271- event_loop .stop ()
272246
273247 unsubscribe = store .subscribe (render )
274248
275249 dispatch_actions (store )
276250
277251
278- def test_event_subscription (
279- store : StoreType ,
280- event_loop : LoopThread ,
281- ) -> None :
282- async def finish () -> None :
252+ def test_event_subscription (store : StoreType ) -> None :
253+ async def handler (event : IncrementEvent ) -> None :
283254 await asyncio .sleep (0.1 )
284- event_loop .stop ()
255+ if event .post_value == INCREMENTS :
256+ unsubscribe ()
257+ store .dispatch (FinishAction ())
285258
286- store .subscribe_event (FinishEvent , finish )
287- store .dispatch (FinishAction ())
259+ unsubscribe = store .subscribe_event (IncrementEvent , handler )
288260
289261 dispatch_actions (store )
290262
291263
292- def test_event_subscription_with_no_task_creator (event_loop : LoopThread ) -> None :
264+ def test_event_subscription_with_no_task_creator () -> None :
293265 store = Store (
294266 reducer ,
295267 options = CreateStoreOptions (auto_init = True ),
296268 )
297-
298- async def finish () -> None :
299- await asyncio .sleep (0.1 )
300- event_loop .stop ()
301-
302- store .subscribe_event (FinishEvent , finish )
303269 store .dispatch (FinishAction ())
0 commit comments