use crate::types::{Priority, Timestamp, Value, ValueRange};
use serde::{Deserialize, Serialize};
pub type GoalPriority = Priority;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum GoalStatus {
#[default]
Pending,
Active,
Achieved,
Failed,
Cancelled,
OnHold,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum GoalType {
Achieve {
target: String,
value: Value,
},
Maintain {
target: String,
range: ValueRange,
},
Maximize {
target: String,
},
Minimize {
target: String,
},
Avoid {
condition: String,
},
Perform {
action: String,
},
Respond {
event: String,
},
Custom {
description: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Goal {
pub id: String,
pub name: String,
pub goal_type: GoalType,
pub status: GoalStatus,
pub priority: GoalPriority,
pub created_at: Timestamp,
pub deadline: Option<Timestamp>,
pub progress: f32,
pub parent: Option<String>,
pub subgoals: Vec<String>,
}
impl Goal {
pub fn new(name: &str, goal_type: GoalType) -> Self {
let id = format!("goal_{}", Timestamp::now().0);
Self {
id,
name: name.to_string(),
goal_type,
status: GoalStatus::Pending,
priority: GoalPriority::Normal,
created_at: Timestamp::now(),
deadline: None,
progress: 0.0,
parent: None,
subgoals: Vec::new(),
}
}
pub fn maintain(target: &str, range: impl Into<ValueRange>) -> Self {
Self::new(
&format!("Maintain {}", target),
GoalType::Maintain {
target: target.to_string(),
range: range.into(),
},
)
}
pub fn achieve(target: &str, value: impl Into<Value>) -> Self {
Self::new(
&format!("Achieve {}", target),
GoalType::Achieve {
target: target.to_string(),
value: value.into(),
},
)
}
pub fn maximize(target: &str) -> Self {
Self::new(
&format!("Maximize {}", target),
GoalType::Maximize {
target: target.to_string(),
},
)
}
pub fn minimize(target: &str) -> Self {
Self::new(
&format!("Minimize {}", target),
GoalType::Minimize {
target: target.to_string(),
},
)
}
pub fn avoid(condition: &str) -> Self {
Self::new(
&format!("Avoid {}", condition),
GoalType::Avoid {
condition: condition.to_string(),
},
)
}
pub fn perform(action: &str) -> Self {
Self::new(
&format!("Perform {}", action),
GoalType::Perform {
action: action.to_string(),
},
)
}
pub fn with_priority(mut self, priority: GoalPriority) -> Self {
self.priority = priority;
self
}
pub fn with_deadline(mut self, deadline: Timestamp) -> Self {
self.deadline = Some(deadline);
self
}
pub fn with_parent(mut self, parent_id: String) -> Self {
self.parent = Some(parent_id);
self
}
pub fn activate(&mut self) {
self.status = GoalStatus::Active;
}
pub fn mark_achieved(&mut self) {
self.status = GoalStatus::Achieved;
self.progress = 1.0;
}
pub fn fail(&mut self) {
self.status = GoalStatus::Failed;
}
pub fn cancel(&mut self) {
self.status = GoalStatus::Cancelled;
}
pub fn set_progress(&mut self, progress: f32) {
self.progress = progress.clamp(0.0, 1.0);
}
pub fn is_active(&self) -> bool {
self.status == GoalStatus::Active
}
pub fn is_complete(&self) -> bool {
matches!(
self.status,
GoalStatus::Achieved | GoalStatus::Failed | GoalStatus::Cancelled
)
}
pub fn is_overdue(&self) -> bool {
if let Some(deadline) = self.deadline {
Timestamp::now() > deadline
} else {
false
}
}
pub fn add_subgoal(&mut self, subgoal_id: &str) {
self.subgoals.push(subgoal_id.to_string());
}
}
pub struct GoalManager {
goals: Vec<Goal>,
max_goals: usize,
}
impl GoalManager {
pub fn new(max_goals: usize) -> Self {
Self {
goals: Vec::new(),
max_goals,
}
}
pub fn add(&mut self, goal: Goal) -> Option<String> {
if self.goals.len() >= self.max_goals {
self.goals.retain(|g| !g.is_complete());
}
if self.goals.len() >= self.max_goals {
return None;
}
let id = goal.id.clone();
self.goals.push(goal);
Some(id)
}
pub fn get(&self, id: &str) -> Option<&Goal> {
self.goals.iter().find(|g| g.id == id)
}
pub fn get_mut(&mut self, id: &str) -> Option<&mut Goal> {
self.goals.iter_mut().find(|g| g.id == id)
}
pub fn remove(&mut self, id: &str) {
self.goals.retain(|g| g.id != id);
}
pub fn active_goals(&self) -> Vec<&Goal> {
self.goals.iter().filter(|g| g.is_active()).collect()
}
pub fn pending_goals(&self) -> Vec<&Goal> {
self.goals
.iter()
.filter(|g| g.status == GoalStatus::Pending)
.collect()
}
pub fn highest_priority(&self) -> Option<&Goal> {
self.goals
.iter()
.filter(|g| g.is_active())
.max_by_key(|g| g.priority)
}
pub fn len(&self) -> usize {
self.goals.len()
}
pub fn is_empty(&self) -> bool {
self.goals.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_goal_status_default() {
let status: GoalStatus = Default::default();
assert_eq!(status, GoalStatus::Pending);
}
#[test]
fn test_goal_status_all_variants() {
let statuses = [
GoalStatus::Pending,
GoalStatus::Active,
GoalStatus::Achieved,
GoalStatus::Failed,
GoalStatus::Cancelled,
GoalStatus::OnHold,
];
for status in statuses {
let cloned = status;
assert_eq!(status, cloned);
}
}
#[test]
fn test_goal_status_clone() {
let status = GoalStatus::Active;
let cloned = status.clone();
assert_eq!(status, cloned);
}
#[test]
fn test_goal_status_debug() {
let status = GoalStatus::Achieved;
let debug = format!("{:?}", status);
assert!(debug.contains("Achieved"));
}
#[test]
fn test_goal_status_serialize() {
let status = GoalStatus::Failed;
let json = serde_json::to_string(&status).unwrap();
let parsed: GoalStatus = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, status);
}
#[test]
fn test_goal_status_serialize_all() {
for status in [
GoalStatus::Pending,
GoalStatus::Active,
GoalStatus::Achieved,
GoalStatus::Failed,
GoalStatus::Cancelled,
GoalStatus::OnHold,
] {
let json = serde_json::to_string(&status).unwrap();
let parsed: GoalStatus = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, status);
}
}
#[test]
fn test_goal_type_achieve() {
let goal_type = GoalType::Achieve {
target: "temperature".to_string(),
value: Value::Float(25.0),
};
assert!(matches!(goal_type, GoalType::Achieve { .. }));
}
#[test]
fn test_goal_type_maintain() {
let goal_type = GoalType::Maintain {
target: "humidity".to_string(),
range: ValueRange::new(40.0, 60.0),
};
assert!(matches!(goal_type, GoalType::Maintain { .. }));
}
#[test]
fn test_goal_type_maximize() {
let goal_type = GoalType::Maximize {
target: "efficiency".to_string(),
};
assert!(matches!(goal_type, GoalType::Maximize { .. }));
}
#[test]
fn test_goal_type_minimize() {
let goal_type = GoalType::Minimize {
target: "energy_usage".to_string(),
};
assert!(matches!(goal_type, GoalType::Minimize { .. }));
}
#[test]
fn test_goal_type_avoid() {
let goal_type = GoalType::Avoid {
condition: "overheating".to_string(),
};
assert!(matches!(goal_type, GoalType::Avoid { .. }));
}
#[test]
fn test_goal_type_perform() {
let goal_type = GoalType::Perform {
action: "calibrate_sensors".to_string(),
};
assert!(matches!(goal_type, GoalType::Perform { .. }));
}
#[test]
fn test_goal_type_respond() {
let goal_type = GoalType::Respond {
event: "temperature_alert".to_string(),
};
assert!(matches!(goal_type, GoalType::Respond { .. }));
}
#[test]
fn test_goal_type_custom() {
let goal_type = GoalType::Custom {
description: "Custom goal for testing".to_string(),
};
assert!(matches!(goal_type, GoalType::Custom { .. }));
}
#[test]
fn test_goal_type_clone() {
let goal_type = GoalType::Maximize {
target: "performance".to_string(),
};
let cloned = goal_type.clone();
assert!(matches!(cloned, GoalType::Maximize { target } if target == "performance"));
}
#[test]
fn test_goal_type_debug() {
let goal_type = GoalType::Minimize {
target: "latency".to_string(),
};
let debug = format!("{:?}", goal_type);
assert!(debug.contains("Minimize"));
assert!(debug.contains("latency"));
}
#[test]
fn test_goal_type_serialize() {
let goal_type = GoalType::Achieve {
target: "count".to_string(),
value: Value::Int(100),
};
let json = serde_json::to_string(&goal_type).unwrap();
let parsed: GoalType = serde_json::from_str(&json).unwrap();
assert!(matches!(parsed, GoalType::Achieve { target, .. } if target == "count"));
}
#[test]
fn test_goal_type_serialize_all_variants() {
let types: Vec<GoalType> = vec![
GoalType::Achieve {
target: "x".to_string(),
value: Value::Float(1.0),
},
GoalType::Maintain {
target: "y".to_string(),
range: ValueRange::new(0.0, 10.0),
},
GoalType::Maximize {
target: "z".to_string(),
},
GoalType::Minimize {
target: "w".to_string(),
},
GoalType::Avoid {
condition: "error".to_string(),
},
GoalType::Perform {
action: "action".to_string(),
},
GoalType::Respond {
event: "event".to_string(),
},
GoalType::Custom {
description: "custom".to_string(),
},
];
for goal_type in types {
let json = serde_json::to_string(&goal_type).unwrap();
let _parsed: GoalType = serde_json::from_str(&json).unwrap();
}
}
#[test]
fn test_goal_creation() {
let goal = Goal::maintain("temperature", 20.0..25.0);
assert!(matches!(goal.goal_type, GoalType::Maintain { .. }));
assert_eq!(goal.status, GoalStatus::Pending);
}
#[test]
fn test_goal_new() {
let goal = Goal::new(
"Test Goal",
GoalType::Custom {
description: "Test".to_string(),
},
);
assert!(goal.id.starts_with("goal_"));
assert_eq!(goal.name, "Test Goal");
assert_eq!(goal.status, GoalStatus::Pending);
assert_eq!(goal.priority, Priority::Normal);
assert_eq!(goal.progress, 0.0);
assert!(goal.deadline.is_none());
assert!(goal.parent.is_none());
assert!(goal.subgoals.is_empty());
}
#[test]
fn test_goal_maintain() {
let goal = Goal::maintain("humidity", 40.0..60.0);
assert!(goal.name.contains("Maintain"));
assert!(goal.name.contains("humidity"));
if let GoalType::Maintain { target, range } = &goal.goal_type {
assert_eq!(target, "humidity");
assert_eq!(range.min, Some(40.0));
assert_eq!(range.max, Some(60.0));
} else {
panic!("Expected Maintain goal type");
}
}
#[test]
fn test_goal_achieve() {
let goal = Goal::achieve("score", 100);
assert!(goal.name.contains("Achieve"));
assert!(goal.name.contains("score"));
if let GoalType::Achieve { target, value } = &goal.goal_type {
assert_eq!(target, "score");
assert_eq!(value.as_i64(), Some(100));
} else {
panic!("Expected Achieve goal type");
}
}
#[test]
fn test_goal_maximize() {
let goal = Goal::maximize("efficiency");
assert!(goal.name.contains("Maximize"));
assert!(goal.name.contains("efficiency"));
if let GoalType::Maximize { target } = &goal.goal_type {
assert_eq!(target, "efficiency");
} else {
panic!("Expected Maximize goal type");
}
}
#[test]
fn test_goal_minimize() {
let goal = Goal::minimize("latency");
assert!(goal.name.contains("Minimize"));
assert!(goal.name.contains("latency"));
if let GoalType::Minimize { target } = &goal.goal_type {
assert_eq!(target, "latency");
} else {
panic!("Expected Minimize goal type");
}
}
#[test]
fn test_goal_avoid() {
let goal = Goal::avoid("collision");
assert!(goal.name.contains("Avoid"));
assert!(goal.name.contains("collision"));
if let GoalType::Avoid { condition } = &goal.goal_type {
assert_eq!(condition, "collision");
} else {
panic!("Expected Avoid goal type");
}
}
#[test]
fn test_goal_perform() {
let goal = Goal::perform("calibration");
assert!(goal.name.contains("Perform"));
assert!(goal.name.contains("calibration"));
if let GoalType::Perform { action } = &goal.goal_type {
assert_eq!(action, "calibration");
} else {
panic!("Expected Perform goal type");
}
}
#[test]
fn test_goal_with_priority() {
let goal = Goal::maximize("speed").with_priority(Priority::High);
assert_eq!(goal.priority, Priority::High);
}
#[test]
fn test_goal_with_priority_critical() {
let goal = Goal::minimize("errors").with_priority(Priority::Critical);
assert_eq!(goal.priority, Priority::Critical);
}
#[test]
fn test_goal_with_deadline() {
let deadline = Timestamp::now();
let goal = Goal::achieve("target", 50).with_deadline(deadline);
assert_eq!(goal.deadline, Some(deadline));
}
#[test]
fn test_goal_with_parent() {
let goal = Goal::maximize("efficiency").with_parent("parent_goal_123".to_string());
assert_eq!(goal.parent, Some("parent_goal_123".to_string()));
}
#[test]
fn test_goal_builder_chain() {
let deadline = Timestamp::now();
let goal = Goal::maintain("temperature", 20.0..25.0)
.with_priority(Priority::High)
.with_deadline(deadline)
.with_parent("main_goal".to_string());
assert_eq!(goal.priority, Priority::High);
assert_eq!(goal.deadline, Some(deadline));
assert_eq!(goal.parent, Some("main_goal".to_string()));
}
#[test]
fn test_goal_lifecycle() {
let mut goal = Goal::achieve("count", 100);
assert!(!goal.is_active());
goal.activate();
assert!(goal.is_active());
goal.set_progress(0.5);
assert_eq!(goal.progress, 0.5);
goal.mark_achieved();
assert!(goal.is_complete());
}
#[test]
fn test_goal_activate() {
let mut goal = Goal::maximize("performance");
assert_eq!(goal.status, GoalStatus::Pending);
goal.activate();
assert_eq!(goal.status, GoalStatus::Active);
assert!(goal.is_active());
}
#[test]
fn test_goal_mark_achieved() {
let mut goal = Goal::achieve("target", 100);
goal.activate();
goal.mark_achieved();
assert_eq!(goal.status, GoalStatus::Achieved);
assert_eq!(goal.progress, 1.0);
assert!(goal.is_complete());
}
#[test]
fn test_goal_fail() {
let mut goal = Goal::maximize("success");
goal.activate();
goal.fail();
assert_eq!(goal.status, GoalStatus::Failed);
assert!(goal.is_complete());
}
#[test]
fn test_goal_cancel() {
let mut goal = Goal::perform("action");
goal.activate();
goal.cancel();
assert_eq!(goal.status, GoalStatus::Cancelled);
assert!(goal.is_complete());
}
#[test]
fn test_goal_set_progress() {
let mut goal = Goal::achieve("target", 100);
goal.set_progress(0.5);
assert_eq!(goal.progress, 0.5);
}
#[test]
fn test_goal_set_progress_clamp_high() {
let mut goal = Goal::achieve("target", 100);
goal.set_progress(1.5);
assert_eq!(goal.progress, 1.0);
}
#[test]
fn test_goal_set_progress_clamp_low() {
let mut goal = Goal::achieve("target", 100);
goal.set_progress(-0.5);
assert_eq!(goal.progress, 0.0);
}
#[test]
fn test_goal_progress_updates() {
let mut goal = Goal::maximize("efficiency");
goal.set_progress(0.25);
assert_eq!(goal.progress, 0.25);
goal.set_progress(0.75);
assert_eq!(goal.progress, 0.75);
goal.set_progress(1.0);
assert_eq!(goal.progress, 1.0);
}
#[test]
fn test_goal_is_active() {
let mut goal = Goal::maximize("speed");
assert!(!goal.is_active());
goal.status = GoalStatus::Active;
assert!(goal.is_active());
goal.status = GoalStatus::Pending;
assert!(!goal.is_active());
}
#[test]
fn test_goal_is_complete_achieved() {
let mut goal = Goal::achieve("target", 100);
goal.status = GoalStatus::Achieved;
assert!(goal.is_complete());
}
#[test]
fn test_goal_is_complete_failed() {
let mut goal = Goal::achieve("target", 100);
goal.status = GoalStatus::Failed;
assert!(goal.is_complete());
}
#[test]
fn test_goal_is_complete_cancelled() {
let mut goal = Goal::achieve("target", 100);
goal.status = GoalStatus::Cancelled;
assert!(goal.is_complete());
}
#[test]
fn test_goal_is_not_complete() {
let mut goal = Goal::achieve("target", 100);
goal.status = GoalStatus::Pending;
assert!(!goal.is_complete());
goal.status = GoalStatus::Active;
assert!(!goal.is_complete());
goal.status = GoalStatus::OnHold;
assert!(!goal.is_complete());
}
#[test]
fn test_goal_is_overdue_no_deadline() {
let goal = Goal::maximize("efficiency");
assert!(!goal.is_overdue());
}
#[test]
fn test_goal_is_overdue_future_deadline() {
let future = Timestamp(Timestamp::now().0 + 1_000_000);
let goal = Goal::maximize("efficiency").with_deadline(future);
assert!(!goal.is_overdue());
}
#[test]
fn test_goal_is_overdue_past_deadline() {
let past = Timestamp(0);
let goal = Goal::maximize("efficiency").with_deadline(past);
assert!(goal.is_overdue());
}
#[test]
fn test_goal_add_subgoal() {
let mut goal = Goal::maximize("performance");
assert!(goal.subgoals.is_empty());
goal.add_subgoal("subgoal_1");
assert_eq!(goal.subgoals.len(), 1);
assert_eq!(goal.subgoals[0], "subgoal_1");
}
#[test]
fn test_goal_add_multiple_subgoals() {
let mut goal = Goal::achieve("target", 100);
goal.add_subgoal("sub_1");
goal.add_subgoal("sub_2");
goal.add_subgoal("sub_3");
assert_eq!(goal.subgoals.len(), 3);
assert_eq!(goal.subgoals, vec!["sub_1", "sub_2", "sub_3"]);
}
#[test]
fn test_goal_serialize() {
let goal = Goal::maintain("temperature", 20.0..25.0).with_priority(Priority::High);
let json = serde_json::to_string(&goal).unwrap();
let parsed: Goal = serde_json::from_str(&json).unwrap();
assert_eq!(parsed.name, goal.name);
assert_eq!(parsed.priority, goal.priority);
}
#[test]
fn test_goal_clone() {
let goal = Goal::maximize("efficiency").with_priority(Priority::Critical);
let cloned = goal.clone();
assert_eq!(cloned.name, goal.name);
assert_eq!(cloned.priority, goal.priority);
assert_eq!(cloned.id, goal.id);
}
#[test]
fn test_goal_debug() {
let goal = Goal::minimize("latency");
let debug = format!("{:?}", goal);
assert!(debug.contains("Goal"));
assert!(debug.contains("Minimize"));
}
#[test]
fn test_goal_manager() {
let mut manager = GoalManager::new(5);
let goal1 = Goal::maintain("temp", 20.0..25.0);
let goal2 = Goal::maximize("efficiency");
let id1 = manager.add(goal1).unwrap();
let _id2 = manager.add(goal2).unwrap();
assert_eq!(manager.len(), 2);
manager.get_mut(&id1).unwrap().activate();
assert_eq!(manager.active_goals().len(), 1);
}
#[test]
fn test_goal_manager_new() {
let manager = GoalManager::new(10);
assert!(manager.is_empty());
assert_eq!(manager.len(), 0);
}
#[test]
fn test_goal_manager_add() {
let mut manager = GoalManager::new(5);
let goal = Goal::maximize("performance");
let id = manager.add(goal);
assert!(id.is_some());
assert_eq!(manager.len(), 1);
}
#[test]
fn test_goal_manager_add_at_capacity() {
let mut manager = GoalManager::new(2);
manager.add(Goal::maximize("a")).unwrap();
manager.add(Goal::maximize("b")).unwrap();
let result = manager.add(Goal::maximize("c"));
assert!(result.is_none());
assert_eq!(manager.len(), 2);
}
#[test]
fn test_goal_manager_add_removes_completed() {
let mut manager = GoalManager::new(2);
let id1 = manager.add(Goal::maximize("a")).unwrap();
manager.add(Goal::maximize("b")).unwrap();
manager.get_mut(&id1).unwrap().mark_achieved();
let result = manager.add(Goal::maximize("c"));
assert!(result.is_some());
}
#[test]
fn test_goal_manager_get() {
let mut manager = GoalManager::new(5);
let goal = Goal::maximize("test");
let id = manager.add(goal).unwrap();
let found = manager.get(&id);
assert!(found.is_some());
assert!(found.unwrap().name.contains("Maximize"));
}
#[test]
fn test_goal_manager_get_not_found() {
let manager = GoalManager::new(5);
let found = manager.get("nonexistent_id");
assert!(found.is_none());
}
#[test]
fn test_goal_manager_get_mut() {
let mut manager = GoalManager::new(5);
let goal = Goal::maximize("test");
let id = manager.add(goal).unwrap();
let found = manager.get_mut(&id);
assert!(found.is_some());
found.unwrap().activate();
assert!(manager.get(&id).unwrap().is_active());
}
#[test]
fn test_goal_manager_get_mut_not_found() {
let mut manager = GoalManager::new(5);
let found = manager.get_mut("nonexistent_id");
assert!(found.is_none());
}
#[test]
fn test_goal_manager_remove() {
let mut manager = GoalManager::new(5);
let goal = Goal::maximize("test");
let id = manager.add(goal).unwrap();
assert_eq!(manager.len(), 1);
manager.remove(&id);
assert_eq!(manager.len(), 0);
assert!(manager.get(&id).is_none());
}
#[test]
fn test_goal_manager_remove_nonexistent() {
let mut manager = GoalManager::new(5);
manager.add(Goal::maximize("test")).unwrap();
manager.remove("nonexistent");
assert_eq!(manager.len(), 1); }
#[test]
fn test_goal_manager_active_goals() {
let mut manager = GoalManager::new(5);
let id1 = manager.add(Goal::maximize("a")).unwrap();
let id2 = manager.add(Goal::maximize("b")).unwrap();
manager.add(Goal::maximize("c")).unwrap();
manager.get_mut(&id1).unwrap().activate();
manager.get_mut(&id2).unwrap().activate();
let active = manager.active_goals();
assert_eq!(active.len(), 2);
}
#[test]
fn test_goal_manager_active_goals_empty() {
let mut manager = GoalManager::new(5);
manager.add(Goal::maximize("a")).unwrap();
let active = manager.active_goals();
assert!(active.is_empty());
}
#[test]
fn test_goal_manager_pending_goals() {
let mut manager = GoalManager::new(5);
let id1 = manager.add(Goal::maximize("a")).unwrap();
manager.add(Goal::maximize("b")).unwrap();
manager.add(Goal::maximize("c")).unwrap();
manager.get_mut(&id1).unwrap().activate();
let pending = manager.pending_goals();
assert_eq!(pending.len(), 2);
}
#[test]
fn test_goal_manager_highest_priority() {
let mut manager = GoalManager::new(5);
let id_low = manager
.add(Goal::maximize("low").with_priority(Priority::Low))
.unwrap();
let id_high = manager
.add(Goal::maximize("high").with_priority(Priority::High))
.unwrap();
let id_normal = manager
.add(Goal::maximize("normal").with_priority(Priority::Normal))
.unwrap();
manager.get_mut(&id_low).unwrap().activate();
manager.get_mut(&id_high).unwrap().activate();
manager.get_mut(&id_normal).unwrap().activate();
let highest = manager.highest_priority();
assert!(highest.is_some());
assert_eq!(highest.unwrap().priority, Priority::High);
}
#[test]
fn test_goal_manager_highest_priority_no_active() {
let mut manager = GoalManager::new(5);
manager
.add(Goal::maximize("test").with_priority(Priority::High))
.unwrap();
let highest = manager.highest_priority();
assert!(highest.is_none());
}
#[test]
fn test_goal_manager_len() {
let mut manager = GoalManager::new(5);
assert_eq!(manager.len(), 0);
manager.add(Goal::maximize("a")).unwrap();
assert_eq!(manager.len(), 1);
manager.add(Goal::maximize("b")).unwrap();
assert_eq!(manager.len(), 2);
}
#[test]
fn test_goal_manager_is_empty() {
let mut manager = GoalManager::new(5);
assert!(manager.is_empty());
let id = manager.add(Goal::maximize("a")).unwrap();
assert!(!manager.is_empty());
manager.remove(&id);
assert!(manager.is_empty());
}
#[test]
fn test_goal_manager_complex_workflow() {
let mut manager = GoalManager::new(10);
let mut goal1 = Goal::maintain("temp", 20.0..25.0).with_priority(Priority::Critical);
goal1.id = "unique_id_1".to_string();
let g1 = manager.add(goal1).unwrap();
let mut goal2 = Goal::maximize("efficiency").with_priority(Priority::High);
goal2.id = "unique_id_2".to_string();
let g2 = manager.add(goal2).unwrap();
let mut goal3 = Goal::minimize("cost").with_priority(Priority::Normal);
goal3.id = "unique_id_3".to_string();
let g3 = manager.add(goal3).unwrap();
let mut goal4 = Goal::avoid("errors").with_priority(Priority::Low);
goal4.id = "unique_id_4".to_string();
manager.add(goal4).unwrap();
manager.get_mut(&g1).unwrap().activate();
manager.get_mut(&g2).unwrap().activate();
manager.get_mut(&g3).unwrap().activate();
assert_eq!(manager.active_goals().len(), 3);
assert_eq!(manager.pending_goals().len(), 1);
let highest = manager.highest_priority().unwrap();
assert_eq!(highest.priority, Priority::Critical);
manager.get_mut(&g1).unwrap().mark_achieved();
assert_eq!(manager.active_goals().len(), 2);
let highest = manager.highest_priority().unwrap();
assert_eq!(highest.priority, Priority::High);
manager.get_mut(&g2).unwrap().fail();
assert_eq!(manager.active_goals().len(), 1);
}
}