use crate::{
world::sync::{
host_entity_channel::HostEntityChannel,
remote_entity_channel::{EntityChannelState, RemoteEntityChannel},
},
BigMapKey, ComponentKind, EntityAuthStatus, EntityCommand, EntityMessage, GlobalEntity,
HostType, LocalEntityMap, MessageIndex, OwnedLocalEntity,
};
struct TestComponent1;
struct TestComponent2;
struct TestComponent3;
fn component_kind<T: 'static>() -> ComponentKind {
ComponentKind::from(std::any::TypeId::of::<T>())
}
#[test]
fn migration_preserves_component_state() {
let mut channel = RemoteEntityChannel::new(HostType::Client);
let _entity = GlobalEntity::from_u64(1);
let comp1 = component_kind::<TestComponent1>();
let comp2 = component_kind::<TestComponent2>();
let comp3 = component_kind::<TestComponent3>();
channel.insert_component(comp1);
channel.insert_component(comp2);
channel.insert_component(comp3);
channel.insert_component_channel_as_inserted(comp1, 1);
channel.insert_component_channel_as_inserted(comp2, 2);
channel.insert_component_channel_as_inserted(comp3, 3);
let component_kinds = channel.extract_inserted_component_kinds();
assert!(component_kinds.contains(&comp1));
assert!(component_kinds.contains(&comp2));
assert!(component_kinds.contains(&comp3));
assert_eq!(component_kinds.len(), 3);
}
#[test]
fn migration_handles_empty_component_state() {
let channel = RemoteEntityChannel::new(HostType::Client);
let component_kinds = channel.extract_inserted_component_kinds();
assert!(component_kinds.is_empty());
}
#[test]
fn migration_preserves_buffered_operations() {
let mut channel = RemoteEntityChannel::new(HostType::Client);
let _entity = GlobalEntity::from_u64(1);
let comp1 = component_kind::<TestComponent1>();
channel.receive_message(1, EntityMessage::<()>::Spawn(()));
channel.receive_message(2, EntityMessage::<()>::InsertComponent((), comp1));
channel.receive_message(3, EntityMessage::<()>::RemoveComponent((), comp1));
channel.force_drain_all_buffers();
let events = channel.take_incoming_events();
assert_eq!(events.len(), 3); }
#[test]
fn migration_handles_concurrent_operations() {
let mut channel = RemoteEntityChannel::new(HostType::Client);
let _entity = GlobalEntity::from_u64(1);
let comp1 = component_kind::<TestComponent1>();
let comp2 = component_kind::<TestComponent2>();
channel.receive_message(5, EntityMessage::<()>::InsertComponent((), comp2));
channel.receive_message(3, EntityMessage::<()>::InsertComponent((), comp1));
channel.receive_message(1, EntityMessage::<()>::Spawn(()));
channel.receive_message(4, EntityMessage::<()>::RemoveComponent((), comp1));
channel.force_drain_all_buffers();
let events = channel.take_incoming_events();
assert_eq!(events.len(), 4); }
#[test]
fn migration_handles_entity_redirects() {
let mut entity_map = LocalEntityMap::new(HostType::Server);
let old_entity = OwnedLocalEntity::Remote { id: 42, is_static: false };
let new_entity = OwnedLocalEntity::Host { id: 100, is_static: false };
entity_map.install_entity_redirect(old_entity, new_entity);
let redirected = entity_map.apply_entity_redirect(&old_entity);
assert_eq!(redirected, new_entity);
let other_entity = OwnedLocalEntity::Remote { id: 99, is_static: false };
let not_redirected = entity_map.apply_entity_redirect(&other_entity);
assert_eq!(not_redirected, other_entity);
}
#[test]
fn migration_handles_command_replay() {
let mut channel = HostEntityChannel::new(HostType::Server);
let comp1 = component_kind::<TestComponent1>();
let comp2 = component_kind::<TestComponent2>();
let entity = GlobalEntity::from_u64(1);
channel.send_command(EntityCommand::InsertComponent(entity, comp1));
channel.send_command(EntityCommand::InsertComponent(entity, comp2));
channel.send_command(EntityCommand::RemoveComponent(entity, comp1));
let commands = channel.extract_outgoing_commands();
assert_eq!(commands.len(), 3);
}
#[test]
fn migration_handles_invalid_entity() {
let channel = RemoteEntityChannel::new(HostType::Client);
assert_eq!(channel.get_state(), EntityChannelState::Despawned);
let component_kinds = channel.extract_inserted_component_kinds();
assert!(component_kinds.is_empty());
}
#[test]
fn migration_handles_authority_changes() {
let mut channel = HostEntityChannel::new(HostType::Server);
let entity = GlobalEntity::from_u64(1);
channel.send_command(EntityCommand::EnableDelegation(Some(1), entity));
channel.send_command(EntityCommand::SetAuthority(
Some(1),
entity,
EntityAuthStatus::Granted,
));
let commands = channel.extract_outgoing_commands();
assert_eq!(commands.len(), 2);
}
#[test]
fn migration_handles_high_frequency_operations() {
let mut channel = RemoteEntityChannel::new(HostType::Client);
let _entity = GlobalEntity::from_u64(1);
let comp1 = component_kind::<TestComponent1>();
channel.receive_message(1, EntityMessage::<()>::Spawn(()));
channel.receive_message(2, EntityMessage::<()>::InsertComponent((), comp1));
channel.receive_message(3, EntityMessage::<()>::RemoveComponent((), comp1));
let events = channel.take_incoming_events();
assert!(!events.is_empty()); }
#[test]
fn migration_handles_memory_efficiently() {
let mut channel = RemoteEntityChannel::new(HostType::Client);
let _entity = GlobalEntity::from_u64(1);
for i in 0..10 {
let comp = ComponentKind::from(std::any::TypeId::of::<u32>());
channel.insert_component(comp);
channel.insert_component_channel_as_inserted(comp, i as MessageIndex);
}
let component_kinds = channel.extract_inserted_component_kinds();
assert_eq!(component_kinds.len(), 1);
}
#[test]
fn migration_handles_network_failures() {
let entity_map = LocalEntityMap::new(HostType::Server);
let _fake_entity = GlobalEntity::from_u64(999);
let fake_owned = OwnedLocalEntity::Remote { id: 999, is_static: false };
let result = entity_map.apply_entity_redirect(&fake_owned);
assert_eq!(result, fake_owned);
}
#[test]
fn migration_handles_race_conditions() {
let mut channel = RemoteEntityChannel::new(HostType::Client);
let _entity = GlobalEntity::from_u64(1);
let comp1 = component_kind::<TestComponent1>();
channel.receive_message(1, EntityMessage::<()>::Spawn(()));
channel.receive_message(2, EntityMessage::<()>::InsertComponent((), comp1));
channel.receive_message(3, EntityMessage::<()>::RemoveComponent((), comp1));
channel.force_drain_all_buffers();
let events = channel.take_incoming_events();
assert_eq!(events.len(), 3); }
#[test]
fn migration_handles_edge_cases() {
let mut channel = RemoteEntityChannel::new(HostType::Client);
let component_kinds = channel.extract_inserted_component_kinds();
assert!(component_kinds.is_empty());
let comp1 = component_kind::<TestComponent1>();
channel.insert_component(comp1);
channel.insert_component_channel_as_inserted(comp1, 1);
let component_kinds = channel.extract_inserted_component_kinds();
assert_eq!(component_kinds.len(), 1);
assert!(component_kinds.contains(&comp1));
}