pub mod state;
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
use std::path::Path;
use std::io;
use uuid::Uuid;
use state::{State, StateManager};
fn setup_test_env(dir_name: &str) -> io::Result<()> {
if Path::new(dir_name).exists() {
std::fs::remove_dir_all(dir_name)?;
}
std::fs::create_dir_all(dir_name)?;
Ok(())
}
#[test]
fn test_state_creation() {
let payload = json!({"name": "Test State", "value": 42});
let state = state::State::new(payload.clone());
assert_ne!(*state.get_id(), Uuid::nil(), "State ID should not be nil");
assert_eq!(*state.get_payload(), payload, "Payload should match the input");
}
#[test]
fn test_state_manager_creation() {
let dir = "test_manager_creation".to_string();
let _ = setup_test_env(&dir);
let manager = StateManager::new(dir.clone());
assert_eq!(manager.dir, dir, "Directory path should match");
assert!(manager.states.is_empty(), "States should be empty initially");
}
#[test]
fn test_save_and_load_state() -> io::Result<()> {
let dir = "test_save_load".to_string();
let _ = setup_test_env(&dir);
let mut manager = StateManager::new(dir);
let payload = json!({"name": "John", "age": 30});
let state = State::new(payload);
let state_id = state.get_id().clone();
manager.save(state.clone())?;
assert!(manager.states.contains_key(&state_id), "State should be in memory");
let file_path = format!("{}/{}.json", manager.dir, state_id);
assert!(Path::new(&file_path).exists(), "State file should exist");
match manager.load(&state_id)? {
Some(loaded_state) => {
assert_eq!(*loaded_state.get_id(), state_id, "Loaded state ID should match");
assert_eq!(*loaded_state.get_payload(), *state.get_payload(), "Loaded payload should match");
},
None => panic!("Failed to load state"),
}
Ok(())
}
#[test]
fn test_delete_state() -> io::Result<()> {
let dir = "test_delete".to_string();
let _ = setup_test_env(&dir);
let mut manager = StateManager::new(dir);
let state = State::new(json!({"test": "delete"}));
let state_id = state.get_id().clone();
manager.save(state)?;
assert!(manager.states.contains_key(&state_id), "State should be in memory before deletion");
manager.delete(&state_id)?;
assert!(!manager.states.contains_key(&state_id), "State should be removed from memory");
let file_path = format!("{}/{}.json", manager.dir, state_id);
assert!(!Path::new(&file_path).exists(), "State file should be deleted");
assert!(manager.load(&state_id)?.is_none(), "Deleted state should not be loadable");
Ok(())
}
#[test]
fn test_load_from_dir() -> io::Result<()> {
let dir = "test_load_dir".to_string();
let _ = setup_test_env(&dir);
let mut initial_manager = StateManager::new(dir.clone());
let state1 = State::new(json!({"name": "State 1"}));
let state2 = State::new(json!({"name": "State 2"}));
let state3 = State::new(json!({"name": "State 3"}));
let id1 = state1.get_id().clone();
let id2 = state2.get_id().clone();
let id3 = state3.get_id().clone();
initial_manager.save(state1)?;
initial_manager.save(state2)?;
initial_manager.save(state3)?;
let loaded_manager = StateManager::load_from_dir(&dir)?;
assert_eq!(loaded_manager.states.len(), 3, "Should load all 3 states");
assert!(loaded_manager.states.contains_key(&id1), "Should contain state 1");
assert!(loaded_manager.states.contains_key(&id2), "Should contain state 2");
assert!(loaded_manager.states.contains_key(&id3), "Should contain state 3");
Ok(())
}
#[test]
fn test_empty_directory() -> io::Result<()> {
let dir = "test_empty_dir".to_string();
let _ = setup_test_env(&dir);
let manager = StateManager::load_from_dir(&dir)?;
assert!(manager.states.is_empty(), "States should be empty when loading from empty directory");
Ok(())
}
#[test]
fn test_nonexistent_directory() -> io::Result<()> {
let nonexistent_dir = "test_nonexistent_dir".to_string();
if Path::new(&nonexistent_dir).exists() {
std::fs::remove_dir_all(&nonexistent_dir)?;
}
assert!(!Path::new(&nonexistent_dir).exists(), "Test directory should not exist initially");
let manager = StateManager::load_from_dir(&nonexistent_dir)?;
assert!(Path::new(&nonexistent_dir).exists(), "Directory should be created");
assert!(manager.states.is_empty(), "States should be empty");
Ok(())
}
#[test]
fn test_load_nonexistent_state() -> io::Result<()> {
let dir = "test_load_nonexistent".to_string();
let _ = setup_test_env(&dir);
let manager = StateManager::new(dir);
let nonexistent_id = Uuid::new_v4();
assert!(manager.load(&nonexistent_id)?.is_none(), "Should return None for nonexistent state");
Ok(())
}
#[test]
fn test_full_workflow() -> io::Result<()> {
let dir = "test_workflow".to_string();
let _ = setup_test_env(&dir);
let mut manager = StateManager::new(dir.clone());
let payload = json!({"name": "John", "age": 30});
let state = State::new(payload);
let state_id = state.get_id().clone();
manager.save(state.clone())?;
let loaded_manager = StateManager::load_from_dir(&dir)?;
assert_eq!(loaded_manager.states.len(), 1, "Should load the saved state");
let loaded_state = manager.load(&state_id)?.expect("Failed to load state");
assert_eq!(*loaded_state.get_payload(), *state.get_payload(), "Loaded payload should match original");
manager.delete(&state_id)?;
assert!(manager.load(&state_id)?.is_none(), "State should be deleted");
Ok(())
}
#[test]
fn test_clear_dir() -> io::Result<()> {
let dir = "test_clear_dir".to_string();
let _ = setup_test_env(&dir);
let mut manager = StateManager::new(dir.clone());
manager.save(State::new(json!({"test": "clear1"})))?;
manager.save(State::new(json!({"test": "clear2"})))?;
StateManager::clear_dir(&dir)?;
let loaded_manager = StateManager::load_from_dir(&dir)?;
assert!(loaded_manager.states.is_empty(), "Directory should be empty after clearing");
Ok(())
}
}