use std::{
collections::HashSet,
fmt::Debug,
hash::Hash,
ops::{Deref, DerefMut},
};
use bevy::{ecs::query::QueryFilter, prelude::*};
#[derive(Default)]
pub struct AppTest {
app: App,
}
impl AppTest {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn assert_state<S: States>(&self, s: &S) {
self.assert_state_r(s).unwrap();
}
pub fn assert_state_r<S: States + Debug>(&self, s: &S) -> Result<(), String> {
let app_state = self
.app
.world()
.get_resource::<State<S>>()
.ok_or("State not found".to_string())?
.get();
if app_state != s {
return Err(format!("State was not equal: {app_state:?} != {s:?}"));
}
Ok(())
}
pub fn count_all(&mut self) -> usize {
self.count::<()>()
}
pub fn count<F: QueryFilter>(&mut self) -> usize {
let w = self.app.world_mut();
w.query_filtered::<(), F>().iter(w).count()
}
pub fn all_entities(&mut self) -> HashSet<Entity> {
self.entities::<()>()
}
pub fn entities<F: QueryFilter>(&mut self) -> HashSet<Entity> {
let w = self.app.world_mut();
w.query_filtered::<Entity, F>()
.iter(w)
.collect::<HashSet<_>>()
}
pub fn click<K: Clone + Eq + Hash + Send + Sync + 'static>(&mut self, k: K) {
let mut input = self.app.world_mut().resource_mut::<ButtonInput<K>>();
input.press(k.clone());
input.release(k);
self.app.update();
}
pub fn assert_clicked<K: Clone + Eq + Hash + Send + Sync + 'static>(&mut self, k: K) {
self.assert_clicked_r(k).unwrap();
}
pub fn assert_clicked_r<K: Clone + Eq + Hash + Send + Sync + 'static>(
&mut self,
k: K,
) -> Result<(), String> {
let input = self.app.world().resource::<ButtonInput<K>>();
if !input.just_pressed(k) {
return Err("No key was pressed".to_string());
}
Ok(())
}
pub fn send_message<M: Message>(&mut self, m: M) {
self.world_mut().write_message(m);
}
pub fn assert_message<M: Message + PartialEq>(&mut self, m: &M) {
self.assert_message_r(m).unwrap();
}
pub fn assert_message_r<M: Message + PartialEq>(&mut self, m: &M) -> Result<(), String> {
let msgs = self.world().resource::<Messages<M>>();
let mut cursor = msgs.get_cursor();
for msg in cursor.read(msgs) {
if m == msg {
return Ok(());
}
}
Err("Message not found".to_string())
}
pub fn assert_any_message<M: Message>(&mut self) {
self.assert_any_message_r::<M>().unwrap();
}
pub fn assert_any_message_r<M: Message>(&mut self) -> Result<(), String> {
let msgs = self.world().resource::<Messages<M>>();
if msgs.is_empty() {
return Err("Message not found".to_string());
}
Ok(())
}
}
impl From<App> for AppTest {
fn from(value: App) -> Self {
Self { app: value }
}
}
impl Deref for AppTest {
type Target = App;
fn deref(&self) -> &Self::Target {
&self.app
}
}
impl DerefMut for AppTest {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.app
}
}