Squashed 'vendor/ruvector/' content from commit b64c2172
git-subtree-dir: vendor/ruvector git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
This commit is contained in:
@@ -0,0 +1,391 @@
|
||||
//! Unit tests for exo-temporal memory coordinator
|
||||
|
||||
#[cfg(test)]
|
||||
mod causal_cone_query_tests {
|
||||
use super::*;
|
||||
// use exo_temporal::*;
|
||||
|
||||
#[test]
|
||||
fn test_causal_query_past_cone() {
|
||||
// Test querying past causal cone
|
||||
// let mut memory = TemporalMemory::new();
|
||||
//
|
||||
// let now = SubstrateTime::now();
|
||||
// let past1 = memory.store(pattern_at(now - 1000), &[]).unwrap();
|
||||
// let past2 = memory.store(pattern_at(now - 500), &[past1]).unwrap();
|
||||
// let future1 = memory.store(pattern_at(now + 500), &[]).unwrap();
|
||||
//
|
||||
// let results = memory.causal_query(
|
||||
// &query,
|
||||
// now,
|
||||
// CausalConeType::Past
|
||||
// );
|
||||
//
|
||||
// assert!(results.iter().all(|r| r.timestamp <= now));
|
||||
// assert!(results.iter().any(|r| r.id == past1));
|
||||
// assert!(results.iter().any(|r| r.id == past2));
|
||||
// assert!(!results.iter().any(|r| r.id == future1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_causal_query_future_cone() {
|
||||
// Test querying future causal cone
|
||||
// let results = memory.causal_query(
|
||||
// &query,
|
||||
// reference_time,
|
||||
// CausalConeType::Future
|
||||
// );
|
||||
//
|
||||
// assert!(results.iter().all(|r| r.timestamp >= reference_time));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_causal_query_light_cone() {
|
||||
// Test light-cone constraint (relativistic causality)
|
||||
// let velocity = 1.0; // Speed of light
|
||||
// let results = memory.causal_query(
|
||||
// &query,
|
||||
// reference_time,
|
||||
// CausalConeType::LightCone { velocity }
|
||||
// );
|
||||
//
|
||||
// // Verify |delta_x| <= c * |delta_t|
|
||||
// for result in results {
|
||||
// let dt = (result.timestamp - reference_time).abs();
|
||||
// let dx = distance(result.position, query.position);
|
||||
// assert!(dx <= velocity * dt);
|
||||
// }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_causal_distance_calculation() {
|
||||
// Test causal distance in causal graph
|
||||
// let p1 = memory.store(pattern1, &[]).unwrap();
|
||||
// let p2 = memory.store(pattern2, &[p1]).unwrap();
|
||||
// let p3 = memory.store(pattern3, &[p2]).unwrap();
|
||||
//
|
||||
// let distance = memory.causal_graph.distance(p1, p3);
|
||||
// assert_eq!(distance, 2); // Two hops
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod memory_consolidation_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_short_term_to_long_term() {
|
||||
// Test memory consolidation
|
||||
// let mut memory = TemporalMemory::new();
|
||||
//
|
||||
// // Fill short-term buffer
|
||||
// for i in 0..100 {
|
||||
// memory.store(pattern(i), &[]).unwrap();
|
||||
// }
|
||||
//
|
||||
// assert!(memory.short_term.should_consolidate());
|
||||
//
|
||||
// // Trigger consolidation
|
||||
// memory.consolidate();
|
||||
//
|
||||
// // Verify short-term is cleared
|
||||
// assert!(memory.short_term.is_empty());
|
||||
//
|
||||
// // Verify salient patterns moved to long-term
|
||||
// assert!(memory.long_term.size() > 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_salience_filtering() {
|
||||
// Test that only salient patterns are consolidated
|
||||
// let mut memory = TemporalMemory::new();
|
||||
//
|
||||
// let high_salience = pattern_with_salience(0.9);
|
||||
// let low_salience = pattern_with_salience(0.1);
|
||||
//
|
||||
// memory.store(high_salience.clone(), &[]).unwrap();
|
||||
// memory.store(low_salience.clone(), &[]).unwrap();
|
||||
//
|
||||
// memory.consolidate();
|
||||
//
|
||||
// // High salience should be in long-term
|
||||
// assert!(memory.long_term.contains(&high_salience));
|
||||
//
|
||||
// // Low salience should not be
|
||||
// assert!(!memory.long_term.contains(&low_salience));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_salience_computation() {
|
||||
// Test salience scoring
|
||||
// let memory = setup_test_memory();
|
||||
//
|
||||
// let pattern = sample_pattern();
|
||||
// let salience = memory.compute_salience(&pattern);
|
||||
//
|
||||
// // Salience should be between 0 and 1
|
||||
// assert!(salience >= 0.0 && salience <= 1.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_salience_access_frequency() {
|
||||
// Test access frequency component of salience
|
||||
// let mut memory = setup_test_memory();
|
||||
// let p_id = memory.store(pattern, &[]).unwrap();
|
||||
//
|
||||
// // Access multiple times
|
||||
// for _ in 0..10 {
|
||||
// memory.retrieve(p_id);
|
||||
// }
|
||||
//
|
||||
// let salience = memory.compute_salience_for(p_id);
|
||||
// assert!(salience > baseline_salience);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_salience_recency() {
|
||||
// Test recency component
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_salience_causal_importance() {
|
||||
// Test causal importance component
|
||||
// Patterns with many dependents should have higher salience
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_salience_surprise() {
|
||||
// Test surprise component
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod anticipation_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_anticipate_sequential_pattern() {
|
||||
// Test predictive pre-fetch from sequential patterns
|
||||
// let mut memory = setup_test_memory();
|
||||
//
|
||||
// // Establish pattern: A -> B -> C
|
||||
// memory.store_sequence([pattern_a, pattern_b, pattern_c]);
|
||||
//
|
||||
// // Query A, then B
|
||||
// memory.query(&pattern_a);
|
||||
// memory.query(&pattern_b);
|
||||
//
|
||||
// // Anticipate should predict C
|
||||
// let hints = vec![AnticipationHint::SequentialPattern];
|
||||
// memory.anticipate(&hints);
|
||||
//
|
||||
// // Verify C is pre-fetched in cache
|
||||
// assert!(memory.prefetch_cache.contains_key(&hash(pattern_c)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_anticipate_temporal_cycle() {
|
||||
// Test time-of-day pattern anticipation
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_anticipate_causal_chain() {
|
||||
// Test causal dependency prediction
|
||||
// If A causes B and C, querying A should pre-fetch B and C
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_anticipate_cache_hit() {
|
||||
// Test that anticipated queries hit cache
|
||||
// let mut memory = setup_test_memory_with_anticipation();
|
||||
//
|
||||
// // Trigger anticipation
|
||||
// memory.anticipate(&hints);
|
||||
//
|
||||
// // Query anticipated item
|
||||
// let start = now();
|
||||
// let result = memory.query(&anticipated_query);
|
||||
// let duration = now() - start;
|
||||
//
|
||||
// // Should be faster due to cache hit
|
||||
// assert!(duration < baseline_duration / 2);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod causal_graph_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_causal_graph_add_edge() {
|
||||
// Test adding causal edge
|
||||
// let mut graph = CausalGraph::new();
|
||||
// let p1 = PatternId::new();
|
||||
// let p2 = PatternId::new();
|
||||
//
|
||||
// graph.add_edge(p1, p2);
|
||||
//
|
||||
// assert!(graph.has_edge(p1, p2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_causal_graph_forward_edges() {
|
||||
// Test forward edge index (cause -> effects)
|
||||
// graph.add_edge(p1, p2);
|
||||
// graph.add_edge(p1, p3);
|
||||
//
|
||||
// let effects = graph.forward.get(&p1);
|
||||
// assert_eq!(effects.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_causal_graph_backward_edges() {
|
||||
// Test backward edge index (effect -> causes)
|
||||
// graph.add_edge(p1, p3);
|
||||
// graph.add_edge(p2, p3);
|
||||
//
|
||||
// let causes = graph.backward.get(&p3);
|
||||
// assert_eq!(causes.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_causal_graph_shortest_path() {
|
||||
// Test shortest path calculation
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_causal_graph_out_degree() {
|
||||
// Test out-degree for causal importance
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod temporal_knowledge_graph_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_tkg_add_temporal_fact() {
|
||||
// Test adding temporal fact to TKG
|
||||
// let mut tkg = TemporalKnowledgeGraph::new();
|
||||
// let fact = TemporalFact {
|
||||
// subject: entity1,
|
||||
// predicate: relation,
|
||||
// object: entity2,
|
||||
// timestamp: SubstrateTime::now(),
|
||||
// };
|
||||
//
|
||||
// tkg.add_fact(fact);
|
||||
//
|
||||
// assert!(tkg.has_fact(&fact));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tkg_temporal_query() {
|
||||
// Test querying facts within time range
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tkg_temporal_relations() {
|
||||
// Test temporal relation inference
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod short_term_buffer_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_short_term_insert() {
|
||||
// Test inserting into short-term buffer
|
||||
// let mut buffer = ShortTermBuffer::new(capacity: 100);
|
||||
// let id = buffer.insert(pattern);
|
||||
// assert!(buffer.contains(id));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_short_term_capacity() {
|
||||
// Test buffer capacity limits
|
||||
// let mut buffer = ShortTermBuffer::new(capacity: 10);
|
||||
//
|
||||
// for i in 0..20 {
|
||||
// buffer.insert(pattern(i));
|
||||
// }
|
||||
//
|
||||
// assert_eq!(buffer.len(), 10); // Should maintain capacity
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_short_term_eviction() {
|
||||
// Test eviction policy (FIFO or LRU)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_short_term_should_consolidate() {
|
||||
// Test consolidation trigger
|
||||
// let mut buffer = ShortTermBuffer::new(capacity: 100);
|
||||
//
|
||||
// for i in 0..80 {
|
||||
// buffer.insert(pattern(i));
|
||||
// }
|
||||
//
|
||||
// assert!(buffer.should_consolidate()); // > 75% full
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod long_term_store_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_long_term_integrate() {
|
||||
// Test integrating pattern into long-term storage
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_long_term_search() {
|
||||
// Test search in long-term storage
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_long_term_decay() {
|
||||
// Test strategic decay of low-salience
|
||||
// let mut store = LongTermStore::new();
|
||||
//
|
||||
// store.integrate(high_salience_pattern(), 0.9);
|
||||
// store.integrate(low_salience_pattern(), 0.1);
|
||||
//
|
||||
// store.decay_low_salience(0.2); // Threshold
|
||||
//
|
||||
// // High salience should remain
|
||||
// // Low salience should be decayed
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod edge_cases_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_empty_antecedents() {
|
||||
// Test storing pattern with no causal antecedents
|
||||
// let mut memory = TemporalMemory::new();
|
||||
// let id = memory.store(pattern, &[]).unwrap();
|
||||
// assert!(memory.causal_graph.backward.get(&id).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circular_causality() {
|
||||
// Test detecting/handling circular causal dependencies
|
||||
// Should this be allowed or prevented?
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_time_travel_query() {
|
||||
// Test querying with reference_time in the future
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_concurrent_consolidation() {
|
||||
// Test concurrent access during consolidation
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user