use std::path::PathBuf;
use tempfile::TempDir;
use thread_flow::incremental::analyzer::IncrementalAnalyzer;
use thread_flow::incremental::storage::{InMemoryStorage, StorageBackend};
use thread_flow::incremental::types::DependencyEdge;
use tokio::fs;
async fn create_test_file(dir: &TempDir, name: &str, content: &str) -> PathBuf {
let path = dir.path().join(name);
fs::write(&path, content).await.unwrap();
path
}
#[tokio::test]
async fn test_metrics_during_analysis() {
let temp_dir = tempfile::tempdir().unwrap();
let file1 = create_test_file(&temp_dir, "test.rs", "fn test() {}").await;
let storage = Box::new(InMemoryStorage::new());
let mut analyzer = IncrementalAnalyzer::new(storage);
let result = analyzer
.analyze_changes(std::slice::from_ref(&file1))
.await
.unwrap();
assert_eq!(result.changed_files.len(), 1);
assert!(result.cache_hit_rate >= 0.0 && result.cache_hit_rate <= 1.0);
}
#[tokio::test]
async fn test_cache_hit_metrics() {
let temp_dir = tempfile::tempdir().unwrap();
let file1 = create_test_file(&temp_dir, "test.rs", "fn test() {}").await;
let storage = Box::new(InMemoryStorage::new());
let mut analyzer = IncrementalAnalyzer::new(storage);
let result1 = analyzer
.analyze_changes(std::slice::from_ref(&file1))
.await
.unwrap();
assert_eq!(result1.cache_hit_rate, 0.0);
let result2 = analyzer
.analyze_changes(std::slice::from_ref(&file1))
.await
.unwrap();
assert_eq!(result2.cache_hit_rate, 1.0);
}
#[tokio::test]
async fn test_graph_metrics_on_edge_addition() {
let temp_dir = tempfile::tempdir().unwrap();
let file1 = create_test_file(&temp_dir, "a.rs", "fn a() {}").await;
let file2 = create_test_file(&temp_dir, "b.rs", "fn b() {}").await;
let storage = Box::new(InMemoryStorage::new());
let mut analyzer = IncrementalAnalyzer::new(storage);
analyzer
.analyze_changes(&[file1.clone(), file2.clone()])
.await
.unwrap();
let initial_edges = analyzer.graph().edge_count();
analyzer.graph_mut().add_edge(DependencyEdge::new(
file1.clone(),
file2.clone(),
thread_flow::incremental::types::DependencyType::Import,
));
let final_edges = analyzer.graph().edge_count();
assert_eq!(final_edges, initial_edges + 1);
}
#[tokio::test]
async fn test_invalidation_metrics() {
let temp_dir = tempfile::tempdir().unwrap();
let file1 = create_test_file(&temp_dir, "a.rs", "fn a() {}").await;
let file2 = create_test_file(&temp_dir, "b.rs", "fn b() {}").await;
let storage = Box::new(InMemoryStorage::new());
let mut analyzer = IncrementalAnalyzer::new(storage);
analyzer
.analyze_changes(&[file1.clone(), file2.clone()])
.await
.unwrap();
analyzer.graph_mut().add_edge(DependencyEdge::new(
file1.clone(),
file2.clone(),
thread_flow::incremental::types::DependencyType::Import,
));
let affected = analyzer
.invalidate_dependents(std::slice::from_ref(&file2))
.await
.unwrap();
assert!(!affected.is_empty());
assert!(affected.contains(&file1) || affected.contains(&file2));
}
#[tokio::test]
async fn test_storage_metrics() {
let storage = InMemoryStorage::new();
let fp = thread_flow::incremental::types::AnalysisDefFingerprint::new(b"test");
let path = std::path::Path::new("test.rs");
storage.save_fingerprint(path, &fp).await.unwrap();
let loaded = storage.load_fingerprint(path).await.unwrap();
assert!(loaded.is_some());
}