#[derive(Debug, Clone)]
pub struct TrajectoryRecord {
pub primal: Vec<f64>,
pub dual: Vec<f64>,
pub stage_cost: f64,
pub state: Vec<f64>,
}
#[cfg(test)]
mod tests {
use super::TrajectoryRecord;
#[test]
fn construct_and_access_all_fields() {
let record = TrajectoryRecord {
primal: vec![1.0, 2.0, 3.0],
dual: vec![0.5, 0.6],
stage_cost: 42.0,
state: vec![9.0, 8.0],
};
assert_eq!(record.primal, vec![1.0, 2.0, 3.0]);
assert_eq!(record.dual, vec![0.5, 0.6]);
assert_eq!(record.stage_cost, 42.0);
assert_eq!(record.state, vec![9.0, 8.0]);
}
#[test]
fn stage_cost_value_is_accessible() {
let record = TrajectoryRecord {
primal: vec![],
dual: vec![],
stage_cost: 42.0,
state: vec![],
};
assert_eq!(record.stage_cost, 42.0);
}
#[test]
fn clone_produces_identical_independent_copy() {
let original = TrajectoryRecord {
primal: vec![1.0, 2.0],
dual: vec![3.0],
stage_cost: 7.5,
state: vec![4.0, 5.0],
};
let mut cloned = original.clone();
assert_eq!(cloned.primal, original.primal);
assert_eq!(cloned.dual, original.dual);
assert_eq!(cloned.stage_cost, original.stage_cost);
assert_eq!(cloned.state, original.state);
cloned.stage_cost = 0.0;
cloned.primal.push(99.0);
assert_eq!(original.stage_cost, 7.5);
assert_eq!(original.primal.len(), 2);
}
#[test]
fn debug_format_is_non_empty() {
let record = TrajectoryRecord {
primal: vec![1.0],
dual: vec![2.0],
stage_cost: 3.0,
state: vec![4.0],
};
let s = format!("{record:?}");
assert!(!s.is_empty());
}
#[test]
fn flat_vec_indexing_pattern_works_correctly() {
let n_stages: usize = 5;
let scenario: usize = 1;
let mut records: Vec<TrajectoryRecord> = (0_u8..15_u8)
.map(|i| TrajectoryRecord {
primal: vec![],
dual: vec![],
stage_cost: f64::from(i),
state: vec![],
})
.collect();
records[scenario * n_stages + 3].stage_cost = 999.0;
assert_eq!(records[scenario * n_stages + 3].stage_cost, 999.0);
assert_eq!(records[scenario * n_stages + 2].stage_cost, 7.0);
assert_eq!(records[scenario * n_stages + 4].stage_cost, 9.0);
}
}