Skip to content

Commit 6d307c3

Browse files
committed
Add tests for EntityRc.
1 parent cc65b92 commit 6d307c3

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed

crates/bevy_ecs/src/entity_rc.rs

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,136 @@ impl EntityRcSource {
199199
}
200200
}
201201
}
202+
203+
#[cfg(test)]
204+
mod tests {
205+
use crate::{
206+
entity_rc::{EntityRc, EntityRcSource},
207+
world::World,
208+
};
209+
210+
/// Handles any dropped entities, and flushes the world.
211+
fn handle_drops(world: &mut World, source: &EntityRcSource) {
212+
source.handle_dropped_rcs(&mut world.commands());
213+
world.flush();
214+
}
215+
216+
#[test]
217+
fn simple_counting() {
218+
let mut world = World::new();
219+
let source = EntityRcSource::new();
220+
221+
let entity_1 = world.spawn_empty().id();
222+
let rc_1_1 = source.create_rc(entity_1, ());
223+
224+
let entity_2 = world.spawn_empty().id();
225+
let rc_2_1 = source.create_rc(entity_2, ());
226+
227+
let entity_3 = world.spawn_empty().id();
228+
let rc_3_1 = source.create_rc(entity_3, ());
229+
230+
handle_drops(&mut world, &source);
231+
232+
assert!(world.get_entity(entity_1).is_ok());
233+
assert!(world.get_entity(entity_2).is_ok());
234+
assert!(world.get_entity(entity_3).is_ok());
235+
236+
drop(rc_2_1);
237+
238+
// Dropping the rc doesn't do anything until we handle the drops.
239+
assert!(world.get_entity(entity_1).is_ok());
240+
assert!(world.get_entity(entity_2).is_ok());
241+
assert!(world.get_entity(entity_3).is_ok());
242+
243+
handle_drops(&mut world, &source);
244+
245+
// entity_2 is despawned.
246+
assert!(world.get_entity(entity_1).is_ok());
247+
assert!(world.get_entity(entity_2).is_err());
248+
assert!(world.get_entity(entity_3).is_ok());
249+
250+
// Cloning the rc and then dropping the original doesn't drop the entity.
251+
let rc_1_2 = rc_1_1.clone();
252+
drop(rc_1_1);
253+
handle_drops(&mut world, &source);
254+
255+
assert!(world.get_entity(entity_1).is_ok());
256+
assert!(world.get_entity(entity_3).is_ok());
257+
258+
// Dropping all handles will.
259+
drop(rc_1_2);
260+
handle_drops(&mut world, &source);
261+
262+
assert!(world.get_entity(entity_1).is_err());
263+
assert!(world.get_entity(entity_3).is_ok());
264+
265+
// Cloning the handle many times doesn't do anything.
266+
let rc_3_2 = rc_3_1.clone();
267+
let rc_3_3 = rc_3_1.clone();
268+
let rc_3_4 = rc_3_1.clone();
269+
let rc_3_5 = rc_3_1.clone();
270+
handle_drops(&mut world, &source);
271+
272+
assert!(world.get_entity(entity_3).is_ok());
273+
274+
// Dropping the rc fewer times than clones still does nothing.
275+
for rc in [rc_3_1, rc_3_2, rc_3_3, rc_3_4] {
276+
drop(rc);
277+
handle_drops(&mut world, &source);
278+
assert!(world.get_entity(entity_3).is_ok());
279+
}
280+
281+
// Dropping the last rc finally drops the entity.
282+
drop(rc_3_5);
283+
handle_drops(&mut world, &source);
284+
assert!(world.get_entity(entity_3).is_err());
285+
}
286+
287+
#[test]
288+
fn weak_handles_dont_keep_entity_alive() {
289+
let mut world = World::new();
290+
let source = EntityRcSource::new();
291+
292+
let entity = world.spawn_empty().id();
293+
let rc = source.create_rc(entity, ());
294+
295+
let weak_1 = EntityRc::downgrade(&rc);
296+
let _weak_2 = EntityRc::downgrade(&rc);
297+
let _weak_3 = EntityRc::downgrade(&rc);
298+
handle_drops(&mut world, &source);
299+
assert!(world.get_entity(entity).is_ok());
300+
301+
// Dropping the one rc is enough to despawn the entity.
302+
drop(rc);
303+
304+
// Bonus: trying to get an rc out of an expired weak doesn't work.
305+
assert!(weak_1.upgrade().is_none());
306+
307+
handle_drops(&mut world, &source);
308+
assert!(world.get_entity(entity).is_err());
309+
}
310+
311+
#[test]
312+
fn weak_handles_can_upgrade() {
313+
let mut world = World::new();
314+
let source = EntityRcSource::new();
315+
316+
let entity = world.spawn_empty().id();
317+
let rc = source.create_rc(entity, ());
318+
319+
let weak = EntityRc::downgrade(&rc);
320+
321+
let upgraded_weak = weak.upgrade();
322+
assert!(upgraded_weak.is_some());
323+
324+
// Dropping the original rc does nothing, since we upgraded the weak.
325+
drop(rc);
326+
handle_drops(&mut world, &source);
327+
assert!(world.get_entity(entity).is_ok());
328+
329+
// Also dropping the upgraded weak (now just an rc) will drop the entity.
330+
drop(upgraded_weak);
331+
handle_drops(&mut world, &source);
332+
assert!(world.get_entity(entity).is_err());
333+
}
334+
}

0 commit comments

Comments
 (0)