use event_simulation::{Simulation, SimulationState};
use multilinear::{Change, MultilinearInfo, MultilinearSimulation};
#[test]
fn test_simulation_events_without_changes() {
let mut info = MultilinearInfo::new();
info.add_aspect();
let event1 = info.add_event().with_change(&[]).unwrap().event();
let event2 = info.add_event().with_change(&[]).unwrap().event();
let mut simulation = MultilinearSimulation::new(info);
assert_eq!(simulation.data(), vec![0]);
assert!(simulation.try_call(event1));
assert_eq!(simulation.data(), vec![0]);
assert!(simulation.try_call(event2));
assert_eq!(simulation.data(), vec![0]);
assert!(simulation.try_revert(event2));
assert_eq!(simulation.data(), vec![0]);
assert!(simulation.try_revert(event1));
assert_eq!(simulation.data(), vec![0]);
}
#[test]
fn test_simulation_linear() {
let mut info = MultilinearInfo::new();
let aspect = info.add_aspect();
let change1 = vec![Change::transition(aspect, 0, 1)];
let change2 = vec![Change::transition(aspect, 1, 2)];
let change3 = vec![Change::transition(aspect, 2, 3)];
let change4 = vec![Change::transition(aspect, 3, 4)];
let change5 = vec![Change::transition(aspect, 4, 5)];
let event1 = info.add_event().with_change(&change1).unwrap().event();
let event2 = info.add_event().with_change(&change2).unwrap().event();
let event3 = info.add_event().with_change(&change3).unwrap().event();
let event4 = info.add_event().with_change(&change4).unwrap().event();
let event5 = info.add_event().with_change(&change5).unwrap().event();
let mut simulation = MultilinearSimulation::new(info);
assert_eq!(simulation.data(), vec![0]);
assert!(simulation.try_call(event1));
assert_eq!(simulation.data(), vec![1]);
assert!(simulation.try_call(event2));
assert_eq!(simulation.data(), vec![2]);
assert!(simulation.try_call(event3));
assert_eq!(simulation.data(), vec![3]);
assert!(simulation.try_call(event4));
assert_eq!(simulation.data(), vec![4]);
assert!(simulation.try_call(event5));
assert_eq!(simulation.data(), vec![5]);
assert!(simulation.try_revert(event5));
assert_eq!(simulation.data(), vec![4]);
assert!(simulation.try_revert(event4));
assert_eq!(simulation.data(), vec![3]);
assert!(simulation.try_revert(event3));
assert_eq!(simulation.data(), vec![2]);
assert!(simulation.try_revert(event2));
assert_eq!(simulation.data(), vec![1]);
assert!(simulation.try_revert(event1));
assert_eq!(simulation.data(), vec![0]);
}
#[test]
fn test_simulation_linear_count() {
let mut info = MultilinearInfo::new();
let aspect = info.add_aspect();
let change1 = vec![Change::transition(aspect, 0, 1)];
let change2 = vec![Change::transition(aspect, 1, 2)];
let change3 = vec![Change::transition(aspect, 2, 3)];
let change4 = vec![Change::transition(aspect, 3, 4)];
let change5 = vec![Change::transition(aspect, 4, 5)];
let event = info
.add_event()
.with_change(&change1)
.unwrap()
.with_change(&change2)
.unwrap()
.with_change(&change3)
.unwrap()
.with_change(&change4)
.unwrap()
.with_change(&change5)
.unwrap()
.event();
let mut simulation = MultilinearSimulation::new(info);
assert_eq!(simulation.data(), vec![0]);
assert!(simulation.try_call(event));
assert_eq!(simulation.data(), vec![1]);
assert!(simulation.try_call(event));
assert_eq!(simulation.data(), vec![2]);
assert!(simulation.try_call(event));
assert_eq!(simulation.data(), vec![3]);
assert!(simulation.try_call(event));
assert_eq!(simulation.data(), vec![4]);
assert!(simulation.try_call(event));
assert_eq!(simulation.data(), vec![5]);
assert!(simulation.try_revert(event));
assert_eq!(simulation.data(), vec![4]);
assert!(simulation.try_revert(event));
assert_eq!(simulation.data(), vec![3]);
assert!(simulation.try_revert(event));
assert_eq!(simulation.data(), vec![2]);
assert!(simulation.try_revert(event));
assert_eq!(simulation.data(), vec![1]);
assert!(simulation.try_revert(event));
assert_eq!(simulation.data(), vec![0]);
}
#[test]
fn test_simulation_branching() {
let mut info = MultilinearInfo::new();
let aspect = info.add_aspect();
let change_start_to_left = vec![Change::transition(aspect, 0, 1)];
let change_start_to_right = vec![Change::transition(aspect, 0, 2)];
let change_right_to_end = vec![Change::transition(aspect, 2, 3)];
let change_left_to_end = vec![Change::transition(aspect, 1, 3)];
let event_start_to_left = info
.add_event()
.with_change(&change_start_to_left)
.unwrap()
.event();
let event_start_to_right = info
.add_event()
.with_change(&change_start_to_right)
.unwrap()
.event();
let event_right_to_end = info
.add_event()
.with_change(&change_right_to_end)
.unwrap()
.event();
let event_left_to_end = info
.add_event()
.with_change(&change_left_to_end)
.unwrap()
.event();
let mut simulation = MultilinearSimulation::new(info);
assert_eq!(simulation.data(), vec![0]);
assert!(simulation.try_call(event_start_to_left));
assert_eq!(simulation.data(), vec![1]);
assert!(simulation.try_call(event_left_to_end));
assert_eq!(simulation.data(), vec![3]);
assert!(simulation.try_revert(event_right_to_end));
assert_eq!(simulation.data(), vec![2]);
assert!(simulation.try_revert(event_start_to_right));
assert_eq!(simulation.data(), vec![0]);
assert!(simulation.try_call(event_start_to_right));
assert_eq!(simulation.data(), vec![2]);
assert!(simulation.try_call(event_right_to_end));
assert_eq!(simulation.data(), vec![3]);
assert!(simulation.try_revert(event_left_to_end));
assert_eq!(simulation.data(), vec![1]);
assert!(simulation.try_revert(event_start_to_left));
assert_eq!(simulation.data(), vec![0]);
}
#[test]
fn test_simulation_back_forth() {
let mut info = MultilinearInfo::new();
let aspect = info.add_aspect();
let change1 = vec![Change::transition(aspect, 0, 1)];
let change2 = vec![Change::transition(aspect, 1, 0)];
let event1 = info.add_event().with_change(&change1).unwrap().event();
let event2 = info.add_event().with_change(&change2).unwrap().event();
let mut simulation = MultilinearSimulation::new(info);
assert_eq!(simulation.data(), vec![0]);
assert!(!simulation.try_call(event2));
assert!(simulation.try_call(event1));
assert_eq!(simulation.data(), vec![1]);
assert!(!simulation.try_call(event1));
assert!(simulation.try_call(event2));
assert_eq!(simulation.data(), vec![0]);
assert!(!simulation.try_revert(event1));
assert!(simulation.try_revert(event2));
assert_eq!(simulation.data(), vec![1]);
assert!(!simulation.try_revert(event2));
assert!(simulation.try_revert(event1));
assert_eq!(simulation.data(), vec![0]);
}
#[test]
fn test_simulation_multiple_aspects_same() {
let mut info = MultilinearInfo::new();
let aspect1 = info.add_aspect();
let aspect2 = info.add_aspect();
let change1 = vec![
Change::transition(aspect1, 0, 1),
Change::transition(aspect2, 0, 1),
];
let change2 = vec![
Change::transition(aspect1, 1, 2),
Change::transition(aspect2, 1, 2),
];
let event1 = info.add_event().with_change(&change1).unwrap().event();
let event2 = info.add_event().with_change(&change2).unwrap().event();
let mut simulation = MultilinearSimulation::new(info);
assert_eq!(simulation.data(), vec![0, 0]);
assert!(simulation.try_call(event1));
assert_eq!(simulation.data(), vec![1, 1]);
assert!(simulation.try_call(event2));
assert_eq!(simulation.data(), vec![2, 2]);
assert!(simulation.try_revert(event2));
assert_eq!(simulation.data(), vec![1, 1]);
assert!(simulation.try_revert(event1));
assert_eq!(simulation.data(), vec![0, 0]);
}
#[test]
fn test_simulation_multiple_aspects() {
let mut info = MultilinearInfo::new();
let aspect1 = info.add_aspect();
let aspect2 = info.add_aspect();
let aspect3 = info.add_aspect();
let change1 = vec![
Change::transition(aspect1, 0, 1),
Change::condition(aspect2, 0),
Change::transition(aspect3, 0, 1),
];
let change2 = vec![
Change::transition(aspect1, 1, 2),
Change::transition(aspect3, 1, 0),
];
let change3 = vec![
Change::transition(aspect1, 2, 3),
Change::transition(aspect2, 0, 1),
Change::condition(aspect3, 0),
];
let event1 = info.add_event().with_change(&change1).unwrap().event();
let event2 = info.add_event().with_change(&change2).unwrap().event();
let event3 = info.add_event().with_change(&change3).unwrap().event();
let mut simulation = MultilinearSimulation::new(info);
assert_eq!(simulation.data(), vec![0, 0, 0]);
assert!(simulation.try_call(event1));
assert_eq!(simulation.data(), vec![1, 0, 1]);
assert!(simulation.try_call(event2));
assert_eq!(simulation.data(), vec![2, 0, 0]);
assert!(simulation.try_call(event3));
assert_eq!(simulation.data(), vec![3, 1, 0]);
assert!(simulation.try_revert(event3));
assert_eq!(simulation.data(), vec![2, 0, 0]);
assert!(simulation.try_revert(event2));
assert_eq!(simulation.data(), vec![1, 0, 1]);
assert!(simulation.try_revert(event1));
assert_eq!(simulation.data(), vec![0, 0, 0]);
}
#[test]
fn test_simulation_change_triangle() {
let mut info = MultilinearInfo::new();
let aspect1 = info.add_aspect();
let aspect2 = info.add_aspect();
let aspect3 = info.add_aspect();
let change1 = vec![
Change::transition(aspect1, 0, 1),
Change::transition(aspect2, 0, 1),
];
let change2 = vec![
Change::transition(aspect2, 1, 0),
Change::transition(aspect3, 0, 1),
];
let change3 = vec![
Change::transition(aspect3, 1, 0),
Change::transition(aspect1, 1, 0),
];
let event = info
.add_event()
.with_change(&change1)
.unwrap()
.with_change(&change2)
.unwrap()
.with_change(&change3)
.unwrap()
.event();
let mut simulation = MultilinearSimulation::new(info);
assert_eq!(simulation.data(), vec![0, 0, 0]);
assert!(simulation.try_call(event));
assert_eq!(simulation.data(), vec![1, 1, 0]);
assert!(simulation.try_call(event));
assert_eq!(simulation.data(), vec![1, 0, 1]);
assert!(simulation.try_call(event));
assert_eq!(simulation.data(), vec![0, 0, 0]);
}