rmv_bevy_testing_tools/traits/
manage_state.rs1use bevy_state::state::{FreelyMutableState, NextState, State, States};
2
3use crate::prelude::TestApp;
4
5#[doc = include_str!("./manage_state.md")]
6pub trait ManageState {
7 fn get_state<S: States>(&self) -> Option<&S>;
8 fn get_next_state<S: FreelyMutableState>(&self) -> Option<&NextState<S>>;
9 fn set_next_state<S: FreelyMutableState>(&mut self, next: S) -> Option<()>;
10}
11
12impl ManageState for TestApp {
13 fn get_state<S: States>(&self) -> Option<&S> {
14 self.world().get_resource::<State<S>>().map(|s| s.get())
15 }
16 fn get_next_state<S: FreelyMutableState>(&self) -> Option<&NextState<S>> {
17 self.world().get_resource::<NextState<S>>()
18 }
19 fn set_next_state<S: FreelyMutableState>(&mut self, next: S) -> Option<()> {
20 self.world_mut()
21 .get_resource_mut::<NextState<S>>()
22 .map(|mut s| s.set(next))
23 }
24}
25
26#[cfg(test)]
27mod tests {
28 use std::env;
29
30 use bevy_state::{
31 app::{AppExtStates, StatesPlugin},
32 state::{NextState, States},
33 };
34 use rstest::{fixture, rstest};
35 use speculoos::{assert_that, asserting, option::OptionAssertions, string::StrAssertions};
36
37 use crate::{
38 prelude::{minimal_test_app, TestApp},
39 traits::ManageState,
40 };
41
42 #[rstest]
43 fn trait_manage_state(#[from(minimal_test_app)] mut app: TestApp) {
44 if env::var("_IF_IT_COMPILES_ITS_FINE_")
47 .map(|s| s == "true")
48 .unwrap_or(true)
49 {
50 return;
51 }
52
53 #[derive(States, Debug, Default, Hash, PartialEq, Eq, Clone, Copy)]
54 enum MyState {
55 #[default]
56 A,
57 B,
58 }
59
60 app.init_state::<MyState>();
61 app.set_next_state(MyState::B);
62 }
63
64 #[derive(States, Debug, Copy, Clone, PartialEq, Eq, Hash)]
65 enum MyState {
66 First,
67 Second,
68 }
69
70 #[fixture]
71 fn states_app(
72 #[from(minimal_test_app)]
73 #[with(StatesPlugin)]
74 app: TestApp,
75 ) -> TestApp {
76 app
77 }
78
79 #[rstest]
80 fn test_app_get_state(#[from(states_app)] mut app: TestApp) {
81 asserting!("TestApp::get_state() before MyState exists")
82 .that(&app.get_state::<MyState>())
83 .is_none();
84
85 app.insert_state(MyState::First);
86
87 asserting!("TestApp::get_state() when MyState exists")
88 .that(&app.get_state::<MyState>())
89 .is_some()
90 .is_equal_to(&MyState::First);
91 }
92
93 #[rstest]
94 fn test_app_get_next_state(#[from(states_app)] mut app: TestApp) {
95 asserting!("TestApp::get_next_state() before MyState exists")
96 .that(&app.get_next_state::<MyState>())
97 .is_none();
98
99 app.insert_state(MyState::First);
100
101 let next_state = app.get_next_state::<MyState>();
102
103 asserting!("TestApp::get_next_state() when MyState exists")
104 .that(&next_state)
105 .is_some();
106 assert_that!(format!("{:?}", next_state.unwrap()))
107 .is_equal_to(format!("{:?}", NextState::<MyState>::Unchanged));
108 }
109
110 #[rstest]
111 fn test_app_set_next_state(#[from(states_app)] mut app: TestApp) {
112 asserting!("TestApp::set_next_state() before MyState exists")
113 .that(&app.set_next_state(MyState::First))
114 .is_none();
115
116 app.insert_state(MyState::First);
117 asserting!("TestApp::set_next_state() before MyState exists")
118 .that(&app.set_next_state(MyState::Second))
119 .is_some();
120
121 let next_state = app.get_next_state::<MyState>();
122 asserting!("TestApp::get_next_state() after set_next_state()")
123 .that(&next_state)
124 .is_some();
125 assert_that!(format!("{:?}", next_state.unwrap()))
126 .contains(format!("{:?}", MyState::Second));
127 }
128}