use ecs::component::Component; use ecs::query::term::Without; use ecs::query::{ TermWithFieldTuple as QueryTermWithFieldTuple, TermWithoutFieldTuple as QueryTermWithoutFieldTuple, }; use ecs::uid::Uid; use ecs::{Component, Query, World}; use parking_lot::{Mutex, Once}; pub static SETUP: Once = Once::new(); pub static TEST_LOCK: Mutex<()> = Mutex::new(()); #[derive(Component)] struct A; #[derive(Component)] struct B; #[derive(Component)] struct C; #[derive(Component)] struct D; #[derive(Component)] struct E; #[derive(Component)] struct F; #[derive(Component)] struct G; fn setup() { SETUP.call_once_force(|_| { assert_eq!(A::id().id(), 1); assert_eq!(B::id().id(), 2); assert_eq!(C::id().id(), 3); assert_eq!(D::id().id(), 4); assert_eq!(E::id().id(), 5); assert_eq!(F::id().id(), 6); assert_eq!(G::id().id(), 7); }); } fn assert_query_finds_ents( query: Query<'_, QueryFieldTerms, QueryFieldlessTerms>, mut expected_ent_ids: Vec, ) where QueryFieldTerms: QueryTermWithFieldTuple, QueryFieldlessTerms: QueryTermWithoutFieldTuple, { assert!( query.iter_with_euids().all(|(ent_id, _)| { let Some(index) = expected_ent_ids .iter() .position(|expected_id| *expected_id == ent_id) else { return false; }; expected_ent_ids.remove(index); true }), "Unexpected entity was found. Expected entities left: {expected_ent_ids:?}" ); assert_eq!( expected_ent_ids.len(), 0, concat!( "Not all entities expected to be found was found. ", "Expected entities left: {:?}" ), expected_ent_ids ); } #[test] fn query_archetype_exists_with_edges_to_next_archetypes() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, C)); let ent_2_id = world.create_entity((A, B, C, D, E)); let ent_3_id = world.create_entity((A, B, C, E)); let ent_4_id = world.create_entity((A, B, C, G, F)); assert_query_finds_ents( world.query::<(&A, &B, &C), ()>(), vec![ent_1_id, ent_2_id, ent_3_id, ent_4_id], ); } #[test] fn query_archetype_exists_with_2_comps_diff_to_next_archetype() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, C, D, F)); let ent_2_id = world.create_entity((A, B, F)); assert_query_finds_ents(world.query::<(&A, &B, &F), ()>(), vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_exists_with_2_comps_diff_to_next_archetype_rev() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, F)); let ent_2_id = world.create_entity((A, B, C, D, F)); assert_query_finds_ents(world.query::<(&A, &B, &F), ()>(), vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_exists_with_3_comps_diff_to_next_archetype() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, C, D, E, F)); let ent_2_id = world.create_entity((A, B, F)); assert_query_finds_ents(world.query::<(&A, &B, &F), ()>(), vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_exists_with_3_comps_diff_to_next_archetype_rev() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, F)); let ent_2_id = world.create_entity((A, B, C, D, E, F)); assert_query_finds_ents(world.query::<(&A, &B, &F), ()>(), vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_exists_with_4_comps_diff_to_next_archetype() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, C, D, E, F, G)); let ent_2_id = world.create_entity((A, B, G)); assert_query_finds_ents(world.query::<(&A, &B, &G), ()>(), vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_exists_with_4_comps_diff_to_next_archetype_rev() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, G)); let ent_2_id = world.create_entity((A, B, C, D, E, F, G)); assert_query_finds_ents(world.query::<(&A, &B, &G), ()>(), vec![ent_1_id, ent_2_id]); } #[test] fn query_archetype_exists_with_4_comps_diff_to_next_archetype_and_opt_comp() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, C, D, E, F, G)); let ent_2_id = world.create_entity((A, B, G)); assert_query_finds_ents( world.query::<(&A, &Option, &G), ()>(), vec![ent_1_id, ent_2_id], ); } #[test] fn query_archetype_nonexistant() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); world.create_entity((A, B, C)); let ent_2_id = world.create_entity((A, B, C, D, E)); let ent_3_id = world.create_entity((A, B, C, E)); world.create_entity((A, B, C, G, F)); assert_query_finds_ents(world.query::<(&A, &E), ()>(), vec![ent_2_id, ent_3_id]); } #[test] fn query_archetype_nonexistant_and_opt_comp() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); world.create_entity((A, B, C)); let ent_2_id = world.create_entity((A, B, C, D, E)); let ent_3_id = world.create_entity((A, B, C, E)); world.create_entity((A, B, C, G, F)); assert_query_finds_ents( world.query::<(&A, &E, &Option), ()>(), vec![ent_2_id, ent_3_id], ); } #[test] fn query_without_comp_and_archetype_exists() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); let ent_1_id = world.create_entity((A, B, C)); world.create_entity((A, B, C, E)); world.create_entity((A, B, C, F, E)); let ent_2_id = world.create_entity((A, B, C, G)); let ent_3_id = world.create_entity((A, B, C, G, F)); assert_query_finds_ents( world.query::<(&A, &B, &C), (Without,)>(), vec![ent_1_id, ent_2_id, ent_3_id], ); } #[test] fn query_without_required_comp_and_archetype_exists() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); world.create_entity((A, B, C)); world.create_entity((A, B, C, E)); world.create_entity((A, B, C, F, E)); world.create_entity((A, B, C, G)); world.create_entity((A, B, C, G, F)); assert_query_finds_ents(world.query::<(&A, &B), (Without,)>(), vec![]); } #[test] fn query_without_comp_and_archetype_nonexistant() { setup(); let _test_lock = TEST_LOCK.lock(); let mut world = World::new(); world.create_entity((A, B, C)); let ent_1_id = world.create_entity((A, B, C, E)); world.create_entity((A, B, C, F, E)); let ent_2_id = world.create_entity((A, B, C, G, E)); world.create_entity((A, B, C, G, F, E)); assert_query_finds_ents( world.query::<(&A, &E), (Without,)>(), vec![ent_1_id, ent_2_id], ); }