json_state/
lib.rs

1pub mod state;
2
3#[cfg(test)]
4mod tests {
5    use super::*;
6    use serde_json::json;
7    use std::path::Path;
8    use std::io;
9    use uuid::Uuid;
10    use state::{State, StateManager};
11    
12    // Helper function to create a clean test environment
13    fn setup_test_env(dir_name: &str) -> io::Result<()> {
14        // Clean up the directory to ensure tests start fresh
15        if Path::new(dir_name).exists() {
16            std::fs::remove_dir_all(dir_name)?;
17        }
18        std::fs::create_dir_all(dir_name)?;
19        Ok(())
20    }
21    
22    #[test]
23    fn test_state_creation() {
24        let payload = json!({"name": "Test State", "value": 42});
25        let state = state::State::new(payload.clone());
26        
27        assert_ne!(*state.get_id(), Uuid::nil(), "State ID should not be nil");
28        assert_eq!(*state.get_payload(), payload, "Payload should match the input");
29    }
30    
31    #[test]
32    fn test_state_manager_creation() {
33        let dir = "test_manager_creation".to_string();
34        let _ = setup_test_env(&dir);
35        
36        let manager = StateManager::new(dir.clone());
37        
38        assert_eq!(manager.dir, dir, "Directory path should match");
39        assert!(manager.states.is_empty(), "States should be empty initially");
40    }
41    
42    #[test]
43    fn test_save_and_load_state() -> io::Result<()> {
44        let dir = "test_save_load".to_string();
45        let _ = setup_test_env(&dir);
46        
47        let mut manager = StateManager::new(dir);
48        
49        // Create and save a state
50        let payload = json!({"name": "John", "age": 30});
51        let state = State::new(payload);
52        let state_id = state.get_id().clone();
53        
54        manager.save(state.clone())?;
55        
56        // Verify state is in memory
57        assert!(manager.states.contains_key(&state_id), "State should be in memory");
58        
59        // Verify state file exists
60        let file_path = format!("{}/{}.json", manager.dir, state_id);
61        assert!(Path::new(&file_path).exists(), "State file should exist");
62        
63        // Load the state
64        match manager.load(&state_id)? {
65            Some(loaded_state) => {
66                assert_eq!(*loaded_state.get_id(), state_id, "Loaded state ID should match");
67                assert_eq!(*loaded_state.get_payload(), *state.get_payload(), "Loaded payload should match");
68            },
69            None => panic!("Failed to load state"),
70        }
71        
72        Ok(())
73    }
74    
75    #[test]
76    fn test_delete_state() -> io::Result<()> {
77        let dir = "test_delete".to_string();
78        let _ = setup_test_env(&dir);
79        
80        let mut manager = StateManager::new(dir);
81        
82        // Create and save a state
83        let state = State::new(json!({"test": "delete"}));
84        let state_id = state.get_id().clone();
85        
86        manager.save(state)?;
87        
88        // Verify state exists
89        assert!(manager.states.contains_key(&state_id), "State should be in memory before deletion");
90        
91        // Delete the state
92        manager.delete(&state_id)?;
93        
94        // Verify state is removed from memory
95        assert!(!manager.states.contains_key(&state_id), "State should be removed from memory");
96        
97        // Verify state file is deleted
98        let file_path = format!("{}/{}.json", manager.dir, state_id);
99        assert!(!Path::new(&file_path).exists(), "State file should be deleted");
100        
101        // Attempt to load deleted state
102        assert!(manager.load(&state_id)?.is_none(), "Deleted state should not be loadable");
103        
104        Ok(())
105    }
106    
107    #[test]
108    fn test_load_from_dir() -> io::Result<()> {
109        let dir = "test_load_dir".to_string();
110        let _ = setup_test_env(&dir);
111        
112        // Create initial manager and save some states
113        let mut initial_manager = StateManager::new(dir.clone());
114        
115        let state1 = State::new(json!({"name": "State 1"}));
116        let state2 = State::new(json!({"name": "State 2"}));
117        let state3 = State::new(json!({"name": "State 3"}));
118        
119        let id1 = state1.get_id().clone();
120        let id2 = state2.get_id().clone();
121        let id3 = state3.get_id().clone();
122        
123        initial_manager.save(state1)?;
124        initial_manager.save(state2)?;
125        initial_manager.save(state3)?;
126        
127        // Create a new manager and load states from directory
128        let loaded_manager = StateManager::load_from_dir(&dir)?;
129        
130        // Verify all states were loaded
131        assert_eq!(loaded_manager.states.len(), 3, "Should load all 3 states");
132        assert!(loaded_manager.states.contains_key(&id1), "Should contain state 1");
133        assert!(loaded_manager.states.contains_key(&id2), "Should contain state 2");
134        assert!(loaded_manager.states.contains_key(&id3), "Should contain state 3");
135        
136        Ok(())
137    }
138    
139    #[test]
140    fn test_empty_directory() -> io::Result<()> {
141        let dir = "test_empty_dir".to_string();
142        let _ = setup_test_env(&dir);
143        
144        // Load from an empty directory
145        let manager = StateManager::load_from_dir(&dir)?;
146        
147        assert!(manager.states.is_empty(), "States should be empty when loading from empty directory");
148        
149        Ok(())
150    }
151    
152    #[test]
153    fn test_nonexistent_directory() -> io::Result<()> {
154        let nonexistent_dir = "test_nonexistent_dir".to_string();
155        
156        // Ensure directory doesn't exist
157        if Path::new(&nonexistent_dir).exists() {
158            std::fs::remove_dir_all(&nonexistent_dir)?;
159        }
160        
161        assert!(!Path::new(&nonexistent_dir).exists(), "Test directory should not exist initially");
162        
163        // Load from nonexistent directory (should create it)
164        let manager = StateManager::load_from_dir(&nonexistent_dir)?;
165        
166        // Verify directory was created
167        assert!(Path::new(&nonexistent_dir).exists(), "Directory should be created");
168        assert!(manager.states.is_empty(), "States should be empty");
169        
170        Ok(())
171    }
172    
173    #[test]
174    fn test_load_nonexistent_state() -> io::Result<()> {
175        let dir = "test_load_nonexistent".to_string();
176        let _ = setup_test_env(&dir);
177        
178        let manager = StateManager::new(dir);
179        
180        let nonexistent_id = Uuid::new_v4();
181        assert!(manager.load(&nonexistent_id)?.is_none(), "Should return None for nonexistent state");
182        
183        Ok(())
184    }
185    
186    #[test]
187    fn test_full_workflow() -> io::Result<()> {
188        // This test mimics the workflow from the main.rs example
189        let dir = "test_workflow".to_string();
190        let _ = setup_test_env(&dir);
191        
192        // Create a manager
193        let mut manager = StateManager::new(dir.clone());
194        
195        // Create and save a state
196        let payload = json!({"name": "John", "age": 30});
197        let state = State::new(payload);
198        let state_id = state.get_id().clone();
199        
200        manager.save(state.clone())?;
201        
202        // Load the manager from directory
203        let loaded_manager = StateManager::load_from_dir(&dir)?;
204        assert_eq!(loaded_manager.states.len(), 1, "Should load the saved state");
205        
206        // Load the specific state
207        let loaded_state = manager.load(&state_id)?.expect("Failed to load state");
208        assert_eq!(*loaded_state.get_payload(), *state.get_payload(), "Loaded payload should match original");
209        
210        // Delete the state
211        manager.delete(&state_id)?;
212        
213        // Verify state is deleted
214        assert!(manager.load(&state_id)?.is_none(), "State should be deleted");
215        
216        Ok(())
217    }
218    
219    #[test]
220    fn test_clear_dir() -> io::Result<()> {
221        let dir = "test_clear_dir".to_string();
222        let _ = setup_test_env(&dir);
223        
224        // Create a manager and save some states
225        let mut manager = StateManager::new(dir.clone());
226        manager.save(State::new(json!({"test": "clear1"})))?;
227        manager.save(State::new(json!({"test": "clear2"})))?;
228        
229        // Clear the directory
230        StateManager::clear_dir(&dir)?;
231        
232        // Verify directory is empty
233        let loaded_manager = StateManager::load_from_dir(&dir)?;
234        assert!(loaded_manager.states.is_empty(), "Directory should be empty after clearing");
235        
236        Ok(())
237    }
238}