Skip to content

Commit 17f60e5

Browse files
recovery test
1 parent d20c0c3 commit 17f60e5

File tree

2 files changed

+42
-45
lines changed

2 files changed

+42
-45
lines changed

src/death.rs

Lines changed: 39 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,15 @@
1-
use ixa::{Context, HashMap, IxaError, plan::PlanId, prelude::*};
1+
use ixa::{Context, IxaError, prelude::*};
22

33
use crate::{
44
population_loader::{Alive, Person, PersonId},
55
settings::ContextSettingExt,
66
symptom_status_manager::SymptomStatus,
77
};
88

9-
#[derive(Default)]
10-
struct DeathDataContainer {
11-
plans: HashMap<PersonId, Vec<PlanId>>,
12-
}
13-
14-
impl DeathDataContainer {
15-
fn record_plan(&mut self, person: PersonId, plan: PlanId) {
16-
self.plans.entry(person).or_default().push(plan);
17-
}
18-
19-
fn get_plans(&mut self, person: PersonId) -> Vec<PlanId> {
20-
self.plans.get(&person).cloned().unwrap_or_default()
21-
}
22-
23-
fn remove_plan_records(&mut self, person: PersonId) {
24-
self.plans.remove(&person);
25-
}
26-
}
27-
28-
define_data_plugin!(
29-
DeathDataPlugin,
30-
DeathDataContainer,
31-
DeathDataContainer::default()
32-
);
33-
349
pub trait ContextDeathExt: PluginContext + ContextEntitiesExt {
3510
fn is_alive(&self, person_id: PersonId) -> bool {
3611
self.get_property::<Person, Alive>(person_id).0
3712
}
38-
39-
fn record_plan(&mut self, person_id: PersonId, plan_id: PlanId) {
40-
self.get_data_mut(DeathDataPlugin)
41-
.record_plan(person_id, plan_id);
42-
}
43-
44-
fn cancel_plans(&mut self, person_id: PersonId) {
45-
let plan_ids = self.get_data_mut(DeathDataPlugin).get_plans(person_id);
46-
for plan_id in plan_ids {
47-
self.cancel_plan(&plan_id);
48-
}
49-
self.get_data_mut(DeathDataPlugin)
50-
.remove_plan_records(person_id);
51-
}
5213
}
5314
impl ContextDeathExt for Context {}
5415
pub fn init(context: &mut Context) -> Result<(), IxaError> {
@@ -214,6 +175,39 @@ mod test {
214175
context.execute();
215176
}
216177

178+
#[test]
179+
fn test_dead_person_does_not_recover() {
180+
// This test verifies that when a person is dead, they do not transition to a recovered state.
181+
// We create a person, set them to dead, and then check that their infection status does not change to recovered over the course of the simulation.
182+
let mut context = setup_context(0, 5.0, 0.5, 10.0);
183+
let person_id: PersonId = context.add_entity((Age(30),)).unwrap();
184+
infection_propagation_loop::init(&mut context).unwrap();
185+
symptom_status_manager::init(&mut context).unwrap();
186+
init(&mut context).unwrap();
187+
// We schedule the person to be set to dead at time 0.0,
188+
// and then we check that their infection status does not change to recovered after the death event is processed.
189+
context.add_plan_with_phase(
190+
0.0,
191+
move |context| {
192+
assert!(context.is_alive(person_id));
193+
context.set_property::<Person, SymptomStatus>(person_id, SymptomStatus::Dead);
194+
context.infect_person(person_id, None, None, None);
195+
},
196+
ExecutionPhase::First,
197+
);
198+
context.subscribe_to_event::<PropertyChangeEvent<Person, InfectionStatus>>(
199+
move |_context, event| {
200+
if event.current == InfectionStatus::Recovered {
201+
panic!(
202+
"Dead person should not recover, but person {:?} did",
203+
event.entity_id
204+
);
205+
}
206+
},
207+
);
208+
context.execute();
209+
}
210+
217211
#[test]
218212
fn test_no_infection_when_dead() {
219213
// This test verifies that when a person is dead, they cannot infect others.
@@ -249,11 +243,11 @@ mod test {
249243
// Add a watcher if the other person is infected.
250244
context.subscribe_to_event::<PropertyChangeEvent<Person, InfectionStatus>>(
251245
move |context, event| {
252-
if event.current == InfectionStatus::Infectious {
253-
if event.entity_id != infectious_person {
254-
*num_infected_clone.borrow_mut() += 1;
255-
context.set_property(event.entity_id, InfectionData::Susceptible);
256-
}
246+
if event.current == InfectionStatus::Infectious
247+
&& event.entity_id != infectious_person
248+
{
249+
*num_infected_clone.borrow_mut() += 1;
250+
context.set_property(event.entity_id, InfectionData::Susceptible);
257251
}
258252
},
259253
);

src/infection_propagation_loop.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ fn schedule_next_forecasted_infection(context: &mut Context, person: PersonId) {
1919
}) = get_forecast(context, person)
2020
{
2121
context.add_plan(next_time, move |context| {
22+
if !context.is_alive(person) {
23+
return;
24+
}
2225
let _span = open_span("evaluate and schedule next forecast");
2326
if evaluate_forecast(context, person, forecasted_total_infectiousness) {
2427
let _ = infection_attempt(context, person);

0 commit comments

Comments
 (0)