#[cfg(feature = "builder")]
mod condition_builder_tests {
use openscenario_rs::builder::conditions::{
DistanceConditionBuilder, SpeedConditionBuilder, TimeConditionBuilder, TriggerBuilder,
};
use openscenario_rs::types::{
basic::{Double, Value},
enums::Rule,
positions::{Position, WorldPosition},
};
#[test]
fn test_time_condition_builder() {
let condition = TimeConditionBuilder::new().at_time(5.0).build().unwrap();
assert!(condition.by_value_condition.is_some());
let by_value = condition.by_value_condition.unwrap();
assert!(by_value.simulation_time_condition.is_some());
let time_condition = by_value.simulation_time_condition.unwrap();
assert_eq!(time_condition.value.as_literal().unwrap(), &5.0);
assert_eq!(time_condition.rule, Rule::GreaterThan);
}
#[test]
fn test_time_condition_with_custom_rule() {
let condition = TimeConditionBuilder::new()
.time_rule(10.0, Rule::LessThan)
.build()
.unwrap();
let by_value = condition.by_value_condition.unwrap();
let time_condition = by_value.simulation_time_condition.unwrap();
assert_eq!(time_condition.value.as_literal().unwrap(), &10.0);
assert_eq!(time_condition.rule, Rule::LessThan);
}
#[test]
fn test_speed_condition_builder() {
let condition = SpeedConditionBuilder::new()
.for_entity("ego")
.speed_above(30.0)
.build()
.unwrap();
assert!(condition.by_entity_condition.is_some());
let by_entity = condition.by_entity_condition.unwrap();
assert_eq!(by_entity.triggering_entities.entity_refs.len(), 1);
assert_eq!(
by_entity.triggering_entities.entity_refs[0]
.entity_ref
.as_literal()
.unwrap(),
"ego"
);
match by_entity.entity_condition {
openscenario_rs::types::conditions::entity::EntityCondition::Speed(speed_condition) => {
assert_eq!(speed_condition.value.as_literal().unwrap(), &30.0);
assert_eq!(speed_condition.rule, Rule::GreaterThan);
assert_eq!(speed_condition.entity_ref.as_literal().unwrap(), "ego");
}
_ => panic!("Expected Speed condition"),
}
}
#[test]
fn test_speed_condition_below() {
let condition = SpeedConditionBuilder::new()
.for_entity("target")
.speed_below(15.0)
.build()
.unwrap();
let by_entity = condition.by_entity_condition.unwrap();
match by_entity.entity_condition {
openscenario_rs::types::conditions::entity::EntityCondition::Speed(speed_condition) => {
assert_eq!(speed_condition.value.as_literal().unwrap(), &15.0);
assert_eq!(speed_condition.rule, Rule::LessThan);
}
_ => panic!("Expected Speed condition"),
}
}
#[test]
fn test_distance_condition_builder() {
let position = Position {
world_position: Some(WorldPosition {
x: Double::literal(100.0),
y: Double::literal(200.0),
z: Some(Double::literal(0.0)),
h: Some(Double::literal(0.0)),
p: Some(Double::literal(0.0)),
r: Some(Double::literal(0.0)),
}),
relative_world_position: None,
road_position: None,
relative_road_position: None,
lane_position: None,
relative_lane_position: None,
trajectory_position: None,
geographic_position: None,
relative_object_position: None,
};
let condition = DistanceConditionBuilder::new()
.for_entity("ego")
.to_position(position)
.closer_than(10.0)
.build()
.unwrap();
assert!(condition.by_entity_condition.is_some());
let by_entity = condition.by_entity_condition.unwrap();
match by_entity.entity_condition {
openscenario_rs::types::conditions::entity::EntityCondition::Distance(
distance_condition,
) => {
assert_eq!(distance_condition.value.as_literal().unwrap(), &10.0);
assert_eq!(distance_condition.rule, Rule::LessThan);
assert_eq!(distance_condition.freespace.as_literal().unwrap(), &false);
}
_ => panic!("Expected Distance condition"),
}
}
#[test]
fn test_trigger_builder() {
let time_condition = TimeConditionBuilder::new().at_time(3.0).build().unwrap();
let trigger = TriggerBuilder::new()
.add_condition(time_condition)
.build()
.unwrap();
assert_eq!(trigger.condition_groups.len(), 1);
assert_eq!(trigger.condition_groups[0].conditions.len(), 1);
}
#[test]
fn test_trigger_builder_multiple_conditions() {
let time_condition = TimeConditionBuilder::new().at_time(5.0).build().unwrap();
let speed_condition = SpeedConditionBuilder::new()
.for_entity("ego")
.speed_above(30.0)
.build()
.unwrap();
let trigger = TriggerBuilder::new()
.add_condition_group()
.add_condition(time_condition)
.add_condition(speed_condition)
.finish_group()
.build()
.unwrap();
assert_eq!(trigger.condition_groups.len(), 1);
assert_eq!(trigger.condition_groups[0].conditions.len(), 2);
}
#[test]
fn test_trigger_builder_multiple_groups() {
let time_condition1 = TimeConditionBuilder::new().at_time(3.0).build().unwrap();
let time_condition2 = TimeConditionBuilder::new().at_time(10.0).build().unwrap();
let trigger = TriggerBuilder::new()
.add_condition(time_condition1)
.add_condition(time_condition2)
.build()
.unwrap();
assert_eq!(trigger.condition_groups.len(), 2);
assert_eq!(trigger.condition_groups[0].conditions.len(), 1);
assert_eq!(trigger.condition_groups[1].conditions.len(), 1);
}
#[test]
fn test_condition_validation_errors() {
let result = TimeConditionBuilder::new().build();
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("Time value is required"));
let result = SpeedConditionBuilder::new().speed_above(30.0).build();
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("Entity reference is required"));
let result = SpeedConditionBuilder::new().for_entity("ego").build();
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("Speed value is required"));
let position = Position {
world_position: Some(WorldPosition {
x: Double::literal(0.0),
y: Double::literal(0.0),
z: Some(Double::literal(0.0)),
h: Some(Double::literal(0.0)),
p: Some(Double::literal(0.0)),
r: Some(Double::literal(0.0)),
}),
relative_world_position: None,
road_position: None,
relative_road_position: None,
lane_position: None,
relative_lane_position: None,
trajectory_position: None,
geographic_position: None,
relative_object_position: None,
};
let result = DistanceConditionBuilder::new()
.to_position(position)
.closer_than(10.0)
.build();
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("Entity reference is required"));
let result = TriggerBuilder::new().build();
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("At least one condition is required"));
}
#[test]
fn test_condition_group_builder_fluent_api() {
let trigger = TriggerBuilder::new()
.add_condition_group()
.time_condition()
.at_time(5.0)
.finish()
.unwrap()
.speed_condition()
.for_entity("ego")
.speed_above(25.0)
.finish()
.unwrap()
.finish_group()
.build()
.unwrap();
assert_eq!(trigger.condition_groups.len(), 1);
assert_eq!(trigger.condition_groups[0].conditions.len(), 2);
}
#[test]
fn test_condition_delay_attribute() {
let time_condition = TimeConditionBuilder::new().at_time(5.0).build().unwrap();
assert!(time_condition.delay.is_some());
assert_eq!(time_condition.delay.unwrap().as_literal().unwrap(), &0.0);
let speed_condition = SpeedConditionBuilder::new()
.for_entity("ego")
.speed_above(30.0)
.build()
.unwrap();
assert!(speed_condition.delay.is_some());
assert_eq!(speed_condition.delay.unwrap().as_literal().unwrap(), &0.0);
}
}