@@ -188,6 +188,30 @@ impl StateMachine {
188188 Ok ( neighbors)
189189 }
190190
191+ // TODO: Get all connected memories transitively via BFS
192+ // pub fn get_connected_transitive(&self, id: MemoryId) -> Result<Vec<MemoryId>>
193+
194+ // TODO: Check if path exists between two nodes
195+ // pub fn has_path(&self, from: MemoryId, to: MemoryId) -> bool
196+
197+ // TODO: Delete all memories in a collection
198+ // pub fn delete_collection(&mut self, collection: &str) -> Result<()>
199+
200+ // TODO: Get all unique collection names
201+ // pub fn collections(&self) -> Vec<String>
202+
203+ // TODO: Get count of memories in a collection
204+ // pub fn collection_len(&self, collection: &str) -> usize
205+
206+ // TODO: Get N most recent memories
207+ // pub fn get_latest(&self, n: usize) -> Vec<&MemoryEntry>
208+
209+ // TODO: Get N oldest memories
210+ // pub fn get_oldest(&self, n: usize) -> Vec<&MemoryEntry>
211+
212+ // TODO: Add multiple entries in bulk
213+ // pub fn add_many(&mut self, entries: Vec<MemoryEntry>) -> Result<()>
214+
191215 /// Get size of state
192216 pub fn len ( & self ) -> usize {
193217 self . memories . len ( )
@@ -386,4 +410,149 @@ mod tests {
386410 let result = sm. connect ( MemoryId ( 1 ) , MemoryId ( 2 ) , "bad" . to_string ( ) ) ;
387411 assert ! ( matches!( result, Err ( StateMachineError :: CrossCollectionEdge { .. } ) ) ) ;
388412 }
413+
414+ #[ test]
415+ fn test_disconnect_nonexistent_edge ( ) {
416+ let mut sm = StateMachine :: new ( ) ;
417+ sm. add ( create_test_entry ( 1 , "default" , 1000 ) ) . unwrap ( ) ;
418+ sm. add ( create_test_entry ( 2 , "default" , 1000 ) ) . unwrap ( ) ;
419+
420+ sm. disconnect ( MemoryId ( 1 ) , MemoryId ( 2 ) ) . unwrap ( ) ;
421+ sm. disconnect ( MemoryId ( 1 ) , MemoryId ( 2 ) ) . unwrap ( ) ;
422+
423+ let neighbors = sm. get_neighbors ( MemoryId ( 1 ) ) . unwrap ( ) ;
424+ assert ! ( neighbors. is_empty( ) ) ;
425+ }
426+
427+ #[ test]
428+ fn test_disconnect_from_nonexistent_memory ( ) {
429+ let mut sm = StateMachine :: new ( ) ;
430+ sm. add ( create_test_entry ( 1 , "default" , 1000 ) ) . unwrap ( ) ;
431+
432+ sm. disconnect ( MemoryId ( 999 ) , MemoryId ( 1 ) ) . unwrap ( ) ;
433+ assert_eq ! ( sm. len( ) , 1 ) ;
434+ }
435+
436+ #[ test]
437+ fn test_get_memories_empty_collection ( ) {
438+ let mut sm = StateMachine :: new ( ) ;
439+ sm. add ( create_test_entry ( 1 , "ns1" , 1000 ) ) . unwrap ( ) ;
440+
441+ let ns2_entries = sm. get_memories_in_collection ( "ns2" ) ;
442+ assert ! ( ns2_entries. is_empty( ) ) ;
443+
444+ let default_entries = sm. get_memories_in_collection ( "default" ) ;
445+ assert ! ( default_entries. is_empty( ) ) ;
446+ }
447+
448+ #[ test]
449+ fn test_update_with_same_timestamp ( ) {
450+ let mut sm = StateMachine :: new ( ) ;
451+ sm. add ( create_test_entry ( 1 , "default" , 1000 ) ) . unwrap ( ) ;
452+ sm. add ( create_test_entry ( 1 , "updated_collection" , 1000 ) ) . unwrap ( ) ;
453+
454+ assert_eq ! ( sm. len( ) , 1 ) ;
455+ let entry = sm. get_memory ( MemoryId ( 1 ) ) . unwrap ( ) ;
456+ assert_eq ! ( entry. collection, "updated_collection" ) ;
457+
458+ let range = sm. get_memories_in_time_range ( 1000 , 1000 ) ;
459+ assert_eq ! ( range. len( ) , 1 ) ;
460+ }
461+
462+ #[ test]
463+ fn test_delete_nonexistent_memory ( ) {
464+ let mut sm = StateMachine :: new ( ) ;
465+ sm. add ( create_test_entry ( 1 , "default" , 1000 ) ) . unwrap ( ) ;
466+
467+ let result = sm. delete ( MemoryId ( 999 ) ) ;
468+ assert ! ( matches!( result, Err ( StateMachineError :: MemoryNotFound ( ..) ) ) ) ;
469+ assert_eq ! ( sm. len( ) , 1 ) ;
470+ }
471+
472+ #[ test]
473+ fn test_delete_from_empty_state_machine ( ) {
474+ let mut sm = StateMachine :: new ( ) ;
475+ let result = sm. delete ( MemoryId ( 1 ) ) ;
476+ assert ! ( matches!( result, Err ( StateMachineError :: MemoryNotFound ( ..) ) ) ) ;
477+ }
478+
479+ #[ test]
480+ fn test_connect_self_referential_edge ( ) {
481+ let mut sm = StateMachine :: new ( ) ;
482+ sm. add ( create_test_entry ( 1 , "default" , 1000 ) ) . unwrap ( ) ;
483+
484+ let result = sm. connect ( MemoryId ( 1 ) , MemoryId ( 1 ) , "self_refs" . to_string ( ) ) ;
485+ assert ! ( result. is_ok( ) ) ;
486+
487+ let neighbors = sm. get_neighbors ( MemoryId ( 1 ) ) . unwrap ( ) ;
488+ assert_eq ! ( neighbors. len( ) , 1 ) ;
489+ assert_eq ! ( neighbors[ 0 ] . 0 , MemoryId ( 1 ) ) ;
490+ }
491+
492+ #[ test]
493+ fn test_multiple_edges_same_relation_rejected ( ) {
494+ let mut sm = StateMachine :: new ( ) ;
495+ sm. add ( create_test_entry ( 1 , "default" , 1000 ) ) . unwrap ( ) ;
496+ sm. add ( create_test_entry ( 2 , "default" , 1000 ) ) . unwrap ( ) ;
497+
498+ sm. connect ( MemoryId ( 1 ) , MemoryId ( 2 ) , "rel" . to_string ( ) ) . unwrap ( ) ;
499+ sm. connect ( MemoryId ( 1 ) , MemoryId ( 2 ) , "rel" . to_string ( ) ) . unwrap ( ) ;
500+
501+ let neighbors = sm. get_neighbors ( MemoryId ( 1 ) ) . unwrap ( ) ;
502+ assert_eq ! ( neighbors. len( ) , 1 ) ;
503+ }
504+
505+ #[ test]
506+ fn test_different_relations_allowed ( ) {
507+ let mut sm = StateMachine :: new ( ) ;
508+ sm. add ( create_test_entry ( 1 , "default" , 1000 ) ) . unwrap ( ) ;
509+ sm. add ( create_test_entry ( 2 , "default" , 1000 ) ) . unwrap ( ) ;
510+
511+ sm. connect ( MemoryId ( 1 ) , MemoryId ( 2 ) , "rel1" . to_string ( ) ) . unwrap ( ) ;
512+ sm. connect ( MemoryId ( 1 ) , MemoryId ( 2 ) , "rel2" . to_string ( ) ) . unwrap ( ) ;
513+
514+ let neighbors = sm. get_neighbors ( MemoryId ( 1 ) ) . unwrap ( ) ;
515+ assert_eq ! ( neighbors. len( ) , 2 ) ;
516+ }
517+
518+ #[ test]
519+ fn test_time_range_no_results ( ) {
520+ let mut sm = StateMachine :: new ( ) ;
521+ sm. add ( create_test_entry ( 1 , "default" , 1000 ) ) . unwrap ( ) ;
522+ sm. add ( create_test_entry ( 2 , "default" , 2000 ) ) . unwrap ( ) ;
523+
524+ let range = sm. get_memories_in_time_range ( 500 , 800 ) ;
525+ assert ! ( range. is_empty( ) ) ;
526+
527+ let range = sm. get_memories_in_time_range ( 2500 , 3000 ) ;
528+ assert ! ( range. is_empty( ) ) ;
529+ }
530+
531+ #[ test]
532+ fn test_get_memory_nonexistent ( ) {
533+ let sm = StateMachine :: new ( ) ;
534+ let result = sm. get_memory ( MemoryId ( 1 ) ) ;
535+ assert ! ( matches!( result, Err ( StateMachineError :: MemoryNotFound ( ..) ) ) ) ;
536+ }
537+
538+ #[ test]
539+ fn test_neighbors_nonexistent_memory ( ) {
540+ let sm = StateMachine :: new ( ) ;
541+ let result = sm. get_neighbors ( MemoryId ( 1 ) ) ;
542+ assert ! ( matches!( result, Err ( StateMachineError :: MemoryNotFound ( ..) ) ) ) ;
543+ }
544+
545+ #[ test]
546+ fn test_update_preserves_edges ( ) {
547+ let mut sm = StateMachine :: new ( ) ;
548+ sm. add ( create_test_entry ( 1 , "default" , 1000 ) ) . unwrap ( ) ;
549+ sm. add ( create_test_entry ( 2 , "default" , 1000 ) ) . unwrap ( ) ;
550+ sm. connect ( MemoryId ( 1 ) , MemoryId ( 2 ) , "rel" . to_string ( ) ) . unwrap ( ) ;
551+
552+ sm. add ( create_test_entry ( 1 , "default" , 2000 ) ) . unwrap ( ) ;
553+
554+ let neighbors = sm. get_neighbors ( MemoryId ( 1 ) ) . unwrap ( ) ;
555+ assert_eq ! ( neighbors. len( ) , 1 ) ;
556+ assert_eq ! ( neighbors[ 0 ] . 0 , MemoryId ( 2 ) ) ;
557+ }
389558}
0 commit comments