#![allow(clippy::type_complexity)]
use rand::rngs::StdRng;
use rand::SeedableRng;
use rustsim_core::{
event_queue::{EventContext, EventQueueModel},
prelude::{Agent, AgentStore, HashMapStore},
types::AgentId,
};
mod support;
use support::NothingSpace;
#[derive(Debug, Clone)]
struct Dummy {
id: AgentId,
}
impl Agent for Dummy {
fn id(&self) -> AgentId {
self.id
}
}
type DummyModel = EventQueueModel<NothingSpace, Dummy, HashMapStore<Dummy>, (), StdRng>;
fn noop_action(_agent: &mut Dummy, _ctx: &mut EventContext<'_, NothingSpace, Dummy, (), StdRng>) {}
fn make_model() -> DummyModel {
let mut store = HashMapStore::new();
store.insert(Dummy { id: 1 });
let actions: Vec<fn(&mut Dummy, &mut EventContext<'_, NothingSpace, Dummy, (), StdRng>)> =
vec![noop_action];
EventQueueModel::new(store, NothingSpace, (), StdRng::seed_from_u64(0), actions)
}
#[test]
#[should_panic(expected = "event dt must be finite and non-negative")]
fn add_event_rejects_nan_dt() {
let mut model = make_model();
model.add_event(1, 0, f64::NAN);
}
#[test]
#[should_panic(expected = "event dt must be finite and non-negative")]
fn add_event_rejects_negative_dt() {
let mut model = make_model();
model.add_event(1, 0, -1.0);
}
#[test]
#[should_panic(expected = "event dt must be finite and non-negative")]
fn add_event_rejects_positive_infinity() {
let mut model = make_model();
model.add_event(1, 0, f64::INFINITY);
}
#[test]
#[should_panic(expected = "event dt must be finite and non-negative")]
fn add_event_rejects_negative_infinity() {
let mut model = make_model();
model.add_event(1, 0, f64::NEG_INFINITY);
}
#[test]
fn add_event_accepts_zero_dt() {
let mut model = make_model();
model.add_event(1, 0, 0.0);
assert_eq!(model.queue_len(), 1);
}
#[test]
fn step_event_returns_false_on_empty_queue() {
let mut model = make_model();
assert!(!model.step_event());
}
#[test]
fn step_event_skips_removed_agent_gracefully() {
let mut model = make_model();
model.add_event(1, 0, 1.0);
model.remove_agent(1);
assert!(model.step_event());
assert!(model.queue_is_empty());
}
#[test]
fn step_event_skips_out_of_range_event_idx() {
let mut model = make_model();
model.add_event(1, 99, 1.0);
assert!(model.step_event());
assert!(model.queue_is_empty());
}
#[test]
fn insert_duplicate_agent_returns_err() {
let mut model = make_model();
let duplicate = Dummy { id: 1 };
let result = model.insert_agent(duplicate);
assert!(result.is_err());
let rejected = result.unwrap_err();
assert_eq!(rejected.id, 1);
}
#[test]
fn remove_nonexistent_agent_returns_none() {
let mut model = make_model();
assert!(model.remove_agent(999).is_none());
}