pub(crate) use super::*;
#[derive(Debug, Clone)]
pub(super) struct DoubleGen;
impl SyntheticGenerator for DoubleGen {
type Input = i32;
type Output = i32;
fn generate(&self, seeds: &[i32], _config: &SyntheticConfig) -> Result<Vec<i32>> {
Ok(seeds.iter().map(|x| x * 2).collect())
}
fn quality_score(&self, _: &i32, _: &i32) -> f32 {
1.0
}
fn diversity_score(&self, _: &[i32]) -> f32 {
1.0
}
}
#[test]
fn test_cache_stats_default() {
let stats = CacheStats::default();
assert_eq!(stats.hits, 0);
assert_eq!(stats.misses, 0);
assert_eq!(stats.evictions, 0);
assert_eq!(stats.generations, 0);
}
#[test]
fn test_cache_stats_hit_rate() {
let mut stats = CacheStats::default();
assert!((stats.hit_rate() - 0.0).abs() < f32::EPSILON);
stats.hits = 5;
stats.misses = 5;
assert!((stats.hit_rate() - 0.5).abs() < f32::EPSILON);
stats.misses = 0;
assert!((stats.hit_rate() - 1.0).abs() < f32::EPSILON);
}
#[test]
fn test_cache_new() {
let cache = SyntheticCache::<i32>::new(1000);
assert!(cache.is_empty());
assert_eq!(cache.len(), 0);
assert_eq!(cache.size(), 0);
}
#[test]
fn test_cache_new_min_size() {
let cache = SyntheticCache::<i32>::new(0);
assert_eq!(cache.max_size, 1); }
#[test]
fn test_cache_default() {
let cache = SyntheticCache::<i32>::default();
assert_eq!(cache.max_size, 10 * 1024 * 1024);
}
#[test]
fn test_cache_get_or_generate_first_call() {
let mut cache = SyntheticCache::<i32>::new(10000);
let gen = DoubleGen;
let seeds = vec![1, 2, 3];
let config = SyntheticConfig::default();
let result = cache
.get_or_generate(&seeds, &config, &gen)
.expect("generation failed");
assert_eq!(result, vec![2, 4, 6]);
assert_eq!(cache.stats().misses, 1);
assert_eq!(cache.stats().hits, 0);
assert_eq!(cache.stats().generations, 1);
assert_eq!(cache.len(), 1);
}
#[test]
fn test_cache_get_or_generate_cached() {
let mut cache = SyntheticCache::<i32>::new(10000);
let gen = DoubleGen;
let seeds = vec![1, 2, 3];
let config = SyntheticConfig::default();
let result1 = cache
.get_or_generate(&seeds, &config, &gen)
.expect("generation failed");
let result2 = cache
.get_or_generate(&seeds, &config, &gen)
.expect("generation failed");
assert_eq!(result1, result2);
assert_eq!(cache.stats().hits, 1);
assert_eq!(cache.stats().misses, 1);
assert_eq!(cache.stats().generations, 1); }
#[test]
fn test_cache_different_seeds() {
let mut cache = SyntheticCache::<i32>::new(10000);
let gen = DoubleGen;
let config = SyntheticConfig::default();
let seeds1 = vec![1, 2, 3];
let seeds2 = vec![4, 5, 6];
let result1 = cache
.get_or_generate(&seeds1, &config, &gen)
.expect("failed");
let result2 = cache
.get_or_generate(&seeds2, &config, &gen)
.expect("failed");
assert_eq!(result1, vec![2, 4, 6]);
assert_eq!(result2, vec![8, 10, 12]);
assert_eq!(cache.len(), 2);
assert_eq!(cache.stats().generations, 2);
}
#[test]
fn test_cache_different_config() {
let mut cache = SyntheticCache::<i32>::new(10000);
let gen = DoubleGen;
let seeds = vec![1, 2, 3];
let config1 = SyntheticConfig::default().with_seed(42);
let config2 = SyntheticConfig::default().with_seed(99);
cache
.get_or_generate(&seeds, &config1, &gen)
.expect("failed");
cache
.get_or_generate(&seeds, &config2, &gen)
.expect("failed");
assert_eq!(cache.len(), 2); }
#[test]
fn test_cache_contains() {
let mut cache = SyntheticCache::<i32>::new(10000);
let gen = DoubleGen;
let seeds = vec![1, 2, 3];
let config = SyntheticConfig::default();
assert!(!cache.contains(&seeds, &config));
cache
.get_or_generate(&seeds, &config, &gen)
.expect("failed");
assert!(cache.contains(&seeds, &config));
}
#[test]
fn test_cache_get() {
let mut cache = SyntheticCache::<i32>::new(10000);
let gen = DoubleGen;
let seeds = vec![1, 2, 3];
let config = SyntheticConfig::default();
assert!(cache.get(&seeds, &config).is_none());
cache
.get_or_generate(&seeds, &config, &gen)
.expect("failed");
let result = cache.get(&seeds, &config);
assert!(result.is_some());
assert_eq!(result.expect("should have value"), vec![2, 4, 6]);
}
#[test]
fn test_cache_clear() {
let mut cache = SyntheticCache::<i32>::new(10000);
let gen = DoubleGen;
let seeds = vec![1, 2, 3];
let config = SyntheticConfig::default();
cache
.get_or_generate(&seeds, &config, &gen)
.expect("failed");
assert!(!cache.is_empty());
cache.clear();
assert!(cache.is_empty());
assert_eq!(cache.size(), 0);
}
#[test]
fn test_cache_lru_eviction() {
let mut cache = SyntheticCache::<i32>::new(100);
let gen = DoubleGen;
let config = SyntheticConfig::default();
let seeds1 = vec![1];
let seeds2 = vec![2];
let seeds3 = vec![3];
cache
.get_or_generate(&seeds1, &config, &gen)
.expect("failed");
cache
.get_or_generate(&seeds2, &config, &gen)
.expect("failed");
cache
.get_or_generate(&seeds3, &config, &gen)
.expect("failed");
assert!(cache.stats().evictions > 0);
}
#[test]
fn test_cache_lru_access_order() {
let mut cache = SyntheticCache::<i32>::new(200);
let gen = DoubleGen;
let config = SyntheticConfig::default();
let seeds1 = vec![1];
let seeds2 = vec![2];
let seeds3 = vec![3];
cache
.get_or_generate(&seeds1, &config, &gen)
.expect("failed");
cache
.get_or_generate(&seeds2, &config, &gen)
.expect("failed");
cache
.get_or_generate(&seeds1, &config, &gen)
.expect("failed");
cache
.get_or_generate(&seeds3, &config, &gen)
.expect("failed");
assert!(cache.contains(&seeds1, &config));
assert!(cache.contains(&seeds3, &config));
}
#[test]
fn test_cache_size_tracking() {
let mut cache = SyntheticCache::<i32>::new(10000);
let gen = DoubleGen;
let config = SyntheticConfig::default();
assert_eq!(cache.size(), 0);
cache
.get_or_generate(&[1, 2, 3], &config, &gen)
.expect("failed");
assert!(cache.size() > 0);
let size_after_one = cache.size();
cache
.get_or_generate(&[4, 5, 6], &config, &gen)
.expect("failed");
assert!(cache.size() > size_after_one);
}
#[test]
fn test_cache_hit_rate() {
let mut cache = SyntheticCache::<i32>::new(10000);
let gen = DoubleGen;
let seeds = vec![1, 2, 3];
let config = SyntheticConfig::default();
cache
.get_or_generate(&seeds, &config, &gen)
.expect("failed");
assert!((cache.stats().hit_rate() - 0.0).abs() < f32::EPSILON);
cache
.get_or_generate(&seeds, &config, &gen)
.expect("failed");
assert!((cache.stats().hit_rate() - 0.5).abs() < f32::EPSILON);
cache
.get_or_generate(&seeds, &config, &gen)
.expect("failed");
assert!(cache.stats().hit_rate() > 0.6);
}
#[test]
fn test_cache_with_real_generator() {
use super::super::eda::{EdaConfig, EdaGenerator};
let mut cache = SyntheticCache::<String>::new(100_000);
let gen = EdaGenerator::new(EdaConfig::default());
let seeds = vec!["git status".to_string(), "cargo build".to_string()];
let config = SyntheticConfig::default()
.with_augmentation_ratio(1.0)
.with_quality_threshold(0.3);
let result1 = cache
.get_or_generate(&seeds, &config, &gen)
.expect("generation failed");
let result2 = cache
.get_or_generate(&seeds, &config, &gen)
.expect("cached retrieval failed");
assert_eq!(result1, result2);
assert_eq!(cache.stats().hits, 1);
assert_eq!(cache.stats().generations, 1);
}
#[test]
fn test_cache_determinism() {
let mut cache1 = SyntheticCache::<i32>::new(10000);
let mut cache2 = SyntheticCache::<i32>::new(10000);
let gen = DoubleGen;
let seeds = vec![1, 2, 3];
let config = SyntheticConfig::default();
let result1 = cache1
.get_or_generate(&seeds, &config, &gen)
.expect("failed");
let result2 = cache2
.get_or_generate(&seeds, &config, &gen)
.expect("failed");
assert_eq!(result1, result2);
}