rmv_bevy_testing_tools/
lib.rs

1#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
2
3// TODO: setup tags for different versions of bevy
4
5#[cfg(feature = "speculoos")]
6pub mod assertions;
7#[cfg(feature = "events")]
8pub mod events;
9#[cfg(any(test, feature = "rstest"))]
10pub mod fixtures;
11#[allow(unused_imports)] // silence warning about name starting with test_
12pub mod test_app;
13pub mod traits;
14
15#[cfg(feature = "insta")]
16#[macro_export]
17macro_rules! set_snapshot_suffix {
18    ($($expr:expr),*) => {
19        let mut settings = insta::Settings::clone_current();
20        settings.set_snapshot_suffix(format!($($expr,)*));
21        let _guard = settings.bind_to_scope();
22    }
23}
24
25pub mod prelude {
26    #[cfg(feature = "speculoos")]
27    pub use super::assertions::*;
28    #[cfg(feature = "insta")]
29    pub use super::events::*;
30    #[cfg(any(test, feature = "rstest"))]
31    pub use super::fixtures::*;
32    #[cfg(feature = "insta")]
33    pub use super::set_snapshot_suffix;
34    pub use super::test_app::*;
35    #[allow(unused_imports)]
36    pub use super::traits::*;
37}
38
39#[doc = include_str!("../Readme.md")]
40#[cfg(doctest)]
41pub struct ReadmeDoctests;
42
43#[cfg(test)]
44#[cfg_attr(coverage_nightly, coverage(off))]
45mod tests {
46    #[cfg(feature = "rstest")]
47    use rstest::rstest;
48
49    #[cfg(feature = "rstest")]
50    use crate::prelude::{test_app, TestApp};
51
52    #[cfg(feature = "rstest")]
53    #[rstest]
54    fn with_rstest_fixtures(#[from(test_app)] mut app: TestApp) {
55        // if it compiles, it's fine
56        if skip_feature_test_body() {
57            return;
58        }
59
60        use bevy_app::AppExit;
61
62        use crate::prelude::{CollectEvents, SendEvents};
63
64        app.collect_events::<AppExit>()
65            .send_event_default::<AppExit>();
66    }
67
68    #[cfg(feature = "insta")]
69    #[rstest]
70    fn can_access_insta_macro() {
71        // if it compiles, it's fine
72        if skip_feature_test_body() {
73            return;
74        }
75
76        set_snapshot_suffix!("works");
77    }
78
79    #[cfg(feature = "speculoos")]
80    #[rstest]
81    fn can_access_assertions() {
82        // if it compiles, it's fine
83        if skip_feature_test_body() {
84            return;
85        }
86
87        use speculoos::assert_that;
88
89        use crate::prelude::IsContainedIn;
90
91        let items = vec![1, 2, 3];
92        assert_that!(1).is_contained_in(&items);
93    }
94
95    #[cfg(feature = "iter_tools")]
96    #[rstest]
97    fn can_access_query_vec() {
98        // if it compiles, it's fine
99        if skip_feature_test_body() {
100            return;
101        }
102
103        use bevy_app::App;
104        use bevy_ecs::entity::Entity;
105
106        use crate::{test_app::TestApp, traits::ImmediateQuery};
107
108        TestApp(App::new()).query_vec::<Entity>();
109    }
110
111    #[allow(dead_code)]
112    fn skip_feature_test_body() -> bool {
113        // basically return true always but don't let the compiler know
114        // so it checks code that we don't want to run anyway
115        std::env::var("_SKIP_FEATURE_TESTS_")
116            .map(|s| matches!(s.as_str(), "true" | "1"))
117            .unwrap_or(true)
118    }
119}