Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-core/src/core/model/context_test.rs
StratoSDK / crates / strato-ui-core / src / core / model / context_test.rs
1use super::ModelDropped;
2use crate::{App, Entity};
3 
4#[test]
5fn test_model_spawner() {
6 #[derive(Default)]
7 struct Model {
8 count: usize,
9 }
10 
11 impl Entity for Model {
12 type Event = ();
13 }
14 
15 App::test((), |mut app| async move {
16 let handle = app.add_model(|_| Model::default());
17 
18 let task = handle.update(&mut app, |_model, ctx| {
19 let spawner = ctx.spawner();
20 
21 // Background::spawn requires a 'static future, so this shows that we can move the
22 // ModelSpawner without borrowing anything from the model or ModelContext.
23 ctx.background_executor().spawn(async move {
24 let result = spawner
25 .spawn(move |me, _ctx| {
26 me.count += 1;
27 me.count
28 })
29 .await
30 .expect("Spawn failed");
31 assert_eq!(result, 1);
32 
33 let result = spawner
34 .spawn(move |me, _ctx| {
35 me.count += 1;
36 me.count
37 })
38 .await
39 .expect("Spawn failed");
40 assert_eq!(result, 2);
41 })
42 });
43 
44 task.await.expect("should not fail to join with task");
45 
46 handle.read(&app, |model, _| {
47 assert_eq!(model.count, 2);
48 });
49 })
50}
51 
52#[test]
53fn test_model_spawner_dropped_model() {
54 #[derive(Default)]
55 struct Model {
56 count: usize,
57 }
58 
59 impl Entity for Model {
60 type Event = ();
61 }
62 
63 App::test((), |mut app| async move {
64 let handle = app.add_model(|_| Model::default());
65 
66 let spawner = handle.update(&mut app, |_model, ctx| ctx.spawner());
67 
68 // Explicitly drop the model handle and allow the app to flush effects, removing the task subscriber.
69 app.update(|_| drop(handle));
70 
71 let result = spawner
72 .spawn(|me, _ctx| {
73 me.count += 1;
74 me.count
75 })
76 .await;
77 
78 assert_eq!(result, Err(ModelDropped));
79 })
80}
81