rmv_bevy_testing_tools/
traits.rs

1use bevy_ecs::{
2    event::{Event, SendBatchIds},
3    query::{QueryData, QueryFilter, QuerySingleError, ReadOnlyQueryData, WorldQuery},
4};
5use bevy_state::state::{FreelyMutableState, NextState, States};
6
7pub trait CollectEvents {
8    fn collect_events<E: Event + Clone>(&mut self) -> &mut Self;
9
10    fn collect_events_only<E: Event + Clone + PartialEq>(&mut self, event: E) -> &mut Self;
11
12    fn collect_events_any_of<E: Event + Clone + PartialEq>(&mut self, events: &[E]) -> &mut Self;
13
14    fn get_collected_events<E: Event + Clone>(&self) -> Option<Vec<E>>;
15}
16
17pub trait SendEvents {
18    fn send_event_default<E: Event + Default>(&mut self);
19    fn send_event<E: Event>(&mut self, event: E);
20    fn send_event_batch<E: Event>(
21        &mut self,
22        events: impl IntoIterator<Item = E>,
23    ) -> Option<SendBatchIds<E>>;
24}
25
26pub trait ManageState {
27    fn get_state<S: States>(&self) -> Option<&S>;
28    fn get_next_state<S: FreelyMutableState>(&self) -> Option<&NextState<S>>;
29    fn set_next_state<S: FreelyMutableState>(&mut self, next: S) -> Option<()>;
30}
31
32pub trait BasicQuery {
33    fn query_any<'a, Q, C>(&mut self) -> bool
34    where
35        Q: QueryData<Item<'a> = C>;
36}
37
38pub trait ImmediateQuery {
39    fn query_single<D>(&mut self) -> Result<<D as WorldQuery>::Item<'_>, QuerySingleError>
40    where
41        D: ReadOnlyQueryData;
42    fn query_single_filtered<D, F>(
43        &mut self,
44    ) -> Result<<D as WorldQuery>::Item<'_>, QuerySingleError>
45    where
46        D: ReadOnlyQueryData,
47        F: QueryFilter;
48    fn query_collect<D, C>(&mut self) -> C
49    where
50        D: ReadOnlyQueryData,
51        for<'a> C: std::iter::FromIterator<<D as bevy_ecs::query::WorldQuery>::Item<'a>>;
52    #[cfg(feature = "iter_tools")]
53    fn query_vec<D>(&mut self) -> Vec<<D as WorldQuery>::Item<'_>>
54    where
55        D: ReadOnlyQueryData;
56}
57
58#[cfg(test)]
59mod tests {
60    use rstest::rstest;
61    use speculoos::{assert_that, option::OptionAssertions};
62
63    use super::*;
64    use crate::{app::TestApp, events::CollectedEvents, fixtures::minimal_test_app};
65    #[derive(Event, Clone, Debug, PartialEq)]
66    struct MyEvent;
67
68    #[rstest]
69    fn event_collector_trait_get_collected_events(#[from(minimal_test_app)] mut app: TestApp) {
70        assert_that!(app.get_collected_events::<MyEvent>())
71            .named("no resource")
72            .is_none();
73
74        app.insert_resource(CollectedEvents::<MyEvent>::default());
75
76        assert_that!(app.get_collected_events::<MyEvent>())
77            .named("after resource inserted")
78            .is_some();
79    }
80
81    #[rstest]
82    fn event_collector_trait_collect_events(#[from(minimal_test_app)] mut app: TestApp) {
83        assert_that!(app.get_collected_events::<MyEvent>())
84            .named("no plugin before collect_events")
85            .is_none();
86
87        app.collect_events::<MyEvent>();
88
89        assert_that!(app.get_collected_events::<MyEvent>())
90            .named("plugin inserted after collect_events")
91            .is_some();
92    }
93
94    #[rstest]
95    fn event_collector_trait_collect_events_only(#[from(minimal_test_app)] mut app: TestApp) {
96        assert_that!(app.get_collected_events::<MyEvent>())
97            .named("no plugin before collect_events_only")
98            .is_none();
99
100        app.collect_events_only(MyEvent);
101
102        assert_that!(app.get_collected_events::<MyEvent>())
103            .named("plugin inserted after collect_events_only")
104            .is_some();
105    }
106
107    #[rstest]
108    fn event_collector_trait_collect_events_any_of(#[from(minimal_test_app)] mut app: TestApp) {
109        assert_that!(app.get_collected_events::<MyEvent>())
110            .named("no plugin before collect_events_any_of")
111            .is_none();
112
113        app.collect_events_any_of(&[MyEvent]);
114
115        assert_that!(app.get_collected_events::<MyEvent>())
116            .named("plugin inserted after collect_events_any_of")
117            .is_some();
118    }
119}