use std::collections::HashMap;
use std::time::{SystemTime, UNIX_EPOCH};
use scirs2_core::ndarray::{Array1, Array2, array};
use scirs2_core::random::{Random, rng};
use super::data_types::*;
use super::neural_networks::*;
use super::feature_extraction::*;
use super::ml_models::*;
use super::usage_patterns::*;
use super::recommender_engine::*;
fn create_test_trait_context() -> TraitContext {
TraitContext {
project_type: ProjectType::Library,
domain: Domain::SystemsProgramming,
complexity_level: ComplexityLevel::Intermediate,
crate_size: CrateSize::Medium,
dependencies: vec!["serde".to_string(), "tokio".to_string()],
features_enabled: vec!["async".to_string(), "json".to_string()],
target_audience: TargetAudience::Developers,
performance_requirements: PerformanceRequirements::High,
safety_requirements: SafetyRequirements::Safe,
existing_traits: vec!["Debug".to_string(), "Clone".to_string()],
code_patterns: vec![CodePattern::Builder, CodePattern::Factory],
architectural_style: ArchitecturalStyle::Layered,
error_handling_strategy: ErrorHandlingStrategy::ResultBased,
concurrency_model: ConcurrencyModel::AsyncAwait,
testing_strategy: TestingStrategy::UnitTesting,
documentation_level: DocumentationLevel::Comprehensive,
metadata: HashMap::new(),
}
}
fn create_test_trait_info(name: &str) -> TraitInfo {
TraitInfo {
name: name.to_string(),
category: "Test".to_string(),
description: format!("Test trait {}", name),
complexity: 2,
usage_frequency: 0.5,
dependencies: vec!["core".to_string()],
methods: vec!["test_method".to_string()],
associated_types: vec![],
trait_bounds: vec![],
examples: vec!["Example usage".to_string()],
documentation_url: Some("https://docs.rs/test".to_string()),
version: "1.0.0".to_string(),
}
}
fn create_test_usage_event(trait_name: &str, timestamp: u64) -> UsageEvent {
UsageEvent {
trait_name: trait_name.to_string(),
timestamp,
context: create_test_trait_context(),
user_session: Some("test_user".to_string()),
success: true,
duration_ms: Some(1000),
metadata: HashMap::new(),
}
}
fn create_test_array2(rows: usize, cols: usize) -> Array2<f64> {
Array2::zeros((rows, cols))
}
fn create_test_array1(size: usize) -> Array1<f64> {
Array1::zeros(size)
}
#[allow(non_snake_case)]
#[cfg(test)]
mod data_types_tests {
use super::*;
#[test]
fn test_trait_context_creation() {
let context = create_test_trait_context();
assert_eq!(context.project_type, ProjectType::Library);
assert_eq!(context.domain, Domain::SystemsProgramming);
assert_eq!(context.complexity_level, ComplexityLevel::Intermediate);
}
#[test]
fn test_trait_context_serialization() {
let context = create_test_trait_context();
let serialized = serde_json::to_string(&context).unwrap_or_default();
let deserialized: TraitContext = serde_json::from_str(&serialized).expect("valid JSON operation");
assert_eq!(context.project_type, deserialized.project_type);
}
#[test]
fn test_trait_info_creation() {
let trait_info = create_test_trait_info("TestTrait");
assert_eq!(trait_info.name, "TestTrait");
assert_eq!(trait_info.category, "Test");
assert_eq!(trait_info.complexity, 2);
}
#[test]
fn test_ml_recommendation_config_defaults() {
let config = MLRecommendationConfig::default();
assert_eq!(config.max_recommendations, 10);
assert_eq!(config.min_confidence_threshold, 0.1);
assert!(config.enable_neural_embeddings);
}
#[test]
fn test_trait_recommendation_creation() {
let context = create_test_trait_context();
let recommendation = TraitRecommendation {
trait_name: "TestTrait".to_string(),
confidence: 0.85,
reasoning: "Test reasoning".to_string(),
context: context.clone(),
metadata: HashMap::new(),
};
assert_eq!(recommendation.trait_name, "TestTrait");
assert_eq!(recommendation.confidence, 0.85);
assert_eq!(recommendation.context.project_type, ProjectType::Library);
}
#[test]
fn test_performance_requirements_variants() {
let req = PerformanceRequirements::High;
assert_eq!(format!("{:?}", req), "High");
let req2 = PerformanceRequirements::Low;
assert_eq!(format!("{:?}", req2), "Low");
}
#[test]
fn test_code_pattern_enum() {
let pattern = CodePattern::Builder;
assert_eq!(format!("{:?}", pattern), "Builder");
let pattern2 = CodePattern::Observer;
assert_eq!(format!("{:?}", pattern2), "Observer");
}
}
#[allow(non_snake_case)]
#[cfg(test)]
mod neural_networks_tests {
use super::*;
#[test]
fn test_neural_network_config_creation() {
let config = NeuralNetworkConfig::default();
assert_eq!(config.input_size, 128);
assert_eq!(config.embedding_size, 64);
assert!(config.hidden_layers.len() > 0);
}
#[test]
fn test_neural_embedding_model_creation() {
let config = NeuralNetworkConfig::default();
let model = NeuralEmbeddingModel::new(config);
assert!(model.is_ok());
let model = model.expect("expected valid value");
assert_eq!(model.embedding_dim, 64);
assert_eq!(model.input_weights.nrows(), 128);
assert_eq!(model.input_weights.ncols(), 64);
}
#[test]
fn test_neural_model_forward_pass() {
let config = NeuralNetworkConfig::default();
let model = NeuralEmbeddingModel::new(config).expect("expected valid value");
let input = Array1::zeros(128);
let output = model.forward(&input);
assert!(output.is_ok());
let output = output.expect("expected valid value");
assert_eq!(output.len(), 64);
}
#[test]
fn test_neural_model_training() {
let config = NeuralNetworkConfig::default();
let mut model = NeuralEmbeddingModel::new(config).expect("expected valid value");
let contexts = vec![create_test_trait_context()];
let features = Array2::zeros((1, 128));
let result = model.train(&contexts, &features, 10);
assert!(result.is_ok());
}
#[test]
fn test_activation_functions() {
let config = NeuralNetworkConfig::default();
let model = NeuralEmbeddingModel::new(config).expect("expected valid value");
let input = 0.5;
let relu_output = model.relu(input);
assert_eq!(relu_output, 0.5);
let tanh_output = model.tanh(input);
assert!(tanh_output > 0.0 && tanh_output < 1.0);
let sigmoid_output = model.sigmoid(input);
assert!(sigmoid_output > 0.0 && sigmoid_output < 1.0);
}
#[test]
fn test_model_convergence() {
let config = NeuralNetworkConfig {
learning_rate: 0.01,
..Default::default()
};
let mut model = NeuralEmbeddingModel::new(config).expect("expected valid value");
let contexts = vec![create_test_trait_context(); 10];
let features = Array2::zeros((10, 128));
let initial_loss = model.calculate_loss(&features, &features).expect("calculate_loss should succeed");
model.train(&contexts, &features, 50).expect("train should succeed");
let final_loss = model.calculate_loss(&features, &features).expect("calculate_loss should succeed");
assert!(final_loss <= initial_loss + 0.1);
}
}
#[allow(non_snake_case)]
#[cfg(test)]
mod feature_extraction_tests {
use super::*;
#[test]
fn test_feature_extraction_config() {
let config = FeatureExtractionConfig::default();
assert_eq!(config.feature_dimensions, 128);
assert!(config.enable_text_features);
assert!(config.enable_numerical_features);
}
#[test]
fn test_trait_feature_extractor_creation() {
let config = FeatureExtractionConfig::default();
let extractor = TraitFeatureExtractor::new(config);
assert_eq!(extractor.feature_cache.read().unwrap_or_else(|e| e.into_inner()).len(), 0);
}
#[test]
fn test_context_feature_extraction() {
let config = FeatureExtractionConfig::default();
let mut extractor = TraitFeatureExtractor::new(config);
let context = create_test_trait_context();
let features = extractor.extract_context_features(&context);
assert!(features.is_ok());
let features = features.expect("expected valid value");
assert_eq!(features.len(), 128);
}
#[test]
fn test_text_processing() {
let config = FeatureExtractionConfig::default();
let extractor = TraitFeatureExtractor::new(config);
let text = "This is a test string with multiple words";
let tokens = extractor.tokenize(text);
assert!(tokens.len() > 5);
let stemmed = extractor.stem_word("running");
assert_eq!(stemmed, "run");
}
#[test]
fn test_tfidf_calculation() {
let config = FeatureExtractionConfig::default();
let extractor = TraitFeatureExtractor::new(config);
let documents = vec![
"this is a test document".to_string(),
"another test document here".to_string(),
"final document for testing".to_string(),
];
let tfidf_matrix = extractor.calculate_tfidf(&documents);
assert!(tfidf_matrix.is_ok());
let matrix = tfidf_matrix.expect("expected valid value");
assert_eq!(matrix.nrows(), 3); assert!(matrix.ncols() > 0); }
#[test]
fn test_n_gram_extraction() {
let config = FeatureExtractionConfig::default();
let extractor = TraitFeatureExtractor::new(config);
let tokens = vec!["this".to_string(), "is".to_string(), "a".to_string(), "test".to_string()];
let bigrams = extractor.extract_n_grams(&tokens, 2);
assert!(bigrams.contains(&"this is".to_string()));
assert!(bigrams.contains(&"is a".to_string()));
assert!(bigrams.contains(&"a test".to_string()));
}
#[test]
fn test_stop_word_removal() {
let config = FeatureExtractionConfig::default();
let extractor = TraitFeatureExtractor::new(config);
let tokens = vec![
"the".to_string(), "quick".to_string(), "and".to_string(),
"brown".to_string(), "fox".to_string()
];
let filtered = extractor.remove_stop_words(&tokens);
assert!(!filtered.contains(&"the".to_string()));
assert!(!filtered.contains(&"and".to_string()));
assert!(filtered.contains(&"quick".to_string()));
assert!(filtered.contains(&"brown".to_string()));
assert!(filtered.contains(&"fox".to_string()));
}
#[test]
fn test_feature_caching() {
let config = FeatureExtractionConfig::default();
let mut extractor = TraitFeatureExtractor::new(config);
let context = create_test_trait_context();
let features1 = extractor.extract_context_features(&context).expect("extract_context_features should succeed");
assert_eq!(extractor.feature_cache.read().unwrap_or_else(|e| e.into_inner()).len(), 1);
let features2 = extractor.extract_context_features(&context).expect("extract_context_features should succeed");
assert_eq!(features1.len(), features2.len());
for (a, b) in features1.iter().zip(features2.iter()) {
assert_eq!(a, b);
}
}
}
#[allow(non_snake_case)]
#[cfg(test)]
mod ml_models_tests {
use super::*;
#[test]
fn test_trait_similarity_model_creation() {
let config = MLRecommendationConfig::default();
let model = TraitSimilarityModel::new(config);
assert_eq!(model.similarity_matrix.len(), 0);
assert!(model.clustering_model.is_none());
}
#[test]
fn test_clustering_model_creation() {
let config = ClusteringConfig::default();
let model = ClusteringModel::new(config);
assert!(model.is_ok());
let model = model.expect("expected valid value");
assert_eq!(model.n_clusters, 5);
assert_eq!(model.assignments.len(), 0);
}
#[test]
fn test_clustering_model_fitting() {
let config = ClusteringConfig::default();
let mut model = ClusteringModel::new(config).expect("expected valid value");
let data = Array2::from_shape_vec((10, 5), (0..50).map(|x| x as f64).collect()).expect("valid array shape");
let result = model.fit(&data);
assert!(result.is_ok());
assert_eq!(model.centroids.nrows(), 5); assert_eq!(model.centroids.ncols(), 5); }
#[test]
fn test_clustering_prediction() {
let config = ClusteringConfig::default();
let mut model = ClusteringModel::new(config).expect("expected valid value");
let data = Array2::from_shape_vec((10, 5), (0..50).map(|x| x as f64).collect()).expect("valid array shape");
model.fit(&data).expect("model fitting should succeed");
let sample = Array1::from_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0]);
let cluster = model.predict(&sample);
assert!(cluster.is_ok());
let cluster_id = cluster.expect("expected valid value");
assert!(cluster_id < 5); }
#[test]
fn test_collaborative_filtering_model() {
let config = CollaborativeFilteringConfig::default();
let mut model = CollaborativeFilteringModel::new(config).expect("expected valid value");
let user_trait_matrix = Array2::zeros((5, 10)); let trait_features = Array2::zeros((10, 8));
let result = model.fit(&user_trait_matrix, &trait_features);
assert!(result.is_ok());
}
#[test]
fn test_collaborative_filtering_recommendations() {
let config = CollaborativeFilteringConfig::default();
let mut model = CollaborativeFilteringModel::new(config).expect("expected valid value");
let user_trait_matrix = Array2::from_shape_vec(
(3, 4),
vec![1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0]
).expect("expected valid value");
let trait_features = Array2::zeros((4, 3));
model.fit(&user_trait_matrix, &trait_features).expect("model fitting should succeed");
let user_preferences = Array1::from_vec(vec![1.0, 0.0, 1.0, 0.0]);
let recommendations = model.recommend(&user_preferences, 2);
assert!(recommendations.is_ok());
let recs = recommendations.expect("expected valid value");
assert!(recs.len() <= 2);
}
#[test]
fn test_distance_calculations() {
let config = MLRecommendationConfig::default();
let model = TraitSimilarityModel::new(config);
let a = Array1::from_vec(vec![1.0, 2.0, 3.0]);
let b = Array1::from_vec(vec![4.0, 5.0, 6.0]);
let euclidean = model.calculate_euclidean_distance(&a, &b);
assert!(euclidean > 0.0);
let manhattan = model.calculate_manhattan_distance(&a, &b);
assert!(manhattan > 0.0);
let cosine = model.calculate_cosine_similarity(&a, &b);
assert!(cosine >= -1.0 && cosine <= 1.0);
}
#[test]
fn test_similarity_matrix_operations() {
let config = MLRecommendationConfig::default();
let mut model = TraitSimilarityModel::new(config);
model.set_similarity("TraitA", "TraitB", 0.8);
model.set_similarity("TraitB", "TraitC", 0.6);
let similarity = model.get_similarity("TraitA", "TraitB");
assert_eq!(similarity, 0.8);
let similar_traits = model.find_similar_traits("TraitA", 5);
assert!(similar_traits.is_ok());
}
}
#[allow(non_snake_case)]
#[cfg(test)]
mod usage_patterns_tests {
use super::*;
#[test]
fn test_usage_pattern_config() {
let config = UsagePatternConfig::default();
assert_eq!(config.temporal_window_days, 30);
assert_eq!(config.min_usage_threshold, 5);
assert!(config.trend_analysis_enabled);
}
#[test]
fn test_usage_pattern_analyzer_creation() {
let config = UsagePatternConfig::default();
let feature_extractor = TraitFeatureExtractor::new(FeatureExtractionConfig::default());
let analyzer = UsagePatternAnalyzer::new(config, feature_extractor);
assert_eq!(analyzer.usage_history.len(), 0);
assert_eq!(analyzer.temporal_patterns.len(), 0);
}
#[test]
fn test_usage_event_recording() {
let config = UsagePatternConfig::default();
let feature_extractor = TraitFeatureExtractor::new(FeatureExtractionConfig::default());
let mut analyzer = UsagePatternAnalyzer::new(config, feature_extractor);
let event = create_test_usage_event("TestTrait", 1234567890);
let result = analyzer.record_usage(event);
assert!(result.is_ok());
assert_eq!(analyzer.usage_history.len(), 1);
}
#[test]
fn test_temporal_pattern_analysis() {
let config = UsagePatternConfig::default();
let feature_extractor = TraitFeatureExtractor::new(FeatureExtractionConfig::default());
let mut analyzer = UsagePatternAnalyzer::new(config, feature_extractor);
for i in 0..10 {
let event = create_test_usage_event("TestTrait", 1234567890 + (i * 3600));
analyzer.record_usage(event).expect("record_usage should succeed");
}
let pattern = analyzer.analyze_temporal_patterns("TestTrait");
assert!(pattern.is_ok());
let pattern = pattern.expect("expected valid value");
assert_eq!(pattern.trait_name, "TestTrait");
assert_eq!(pattern.hourly_distribution.len(), 24);
assert_eq!(pattern.weekly_distribution.len(), 7);
}
#[test]
fn test_user_behavior_analysis() {
let config = UsagePatternConfig::default();
let feature_extractor = TraitFeatureExtractor::new(FeatureExtractionConfig::default());
let mut analyzer = UsagePatternAnalyzer::new(config, feature_extractor);
for i in 0..5 {
let event = create_test_usage_event("TestTrait", 1234567890 + (i * 3600));
analyzer.record_usage(event).expect("record_usage should succeed");
}
let behavior = analyzer.analyze_user_behavior("test_user");
assert!(behavior.is_ok());
let behavior = behavior.expect("expected valid value");
assert_eq!(behavior.user_id, "test_user");
assert!(behavior.usage_frequency > 0.0);
assert!(behavior.success_rate > 0.0);
}
#[test]
fn test_seasonal_pattern_detection() {
let config = UsagePatternConfig::default();
let feature_extractor = TraitFeatureExtractor::new(FeatureExtractionConfig::default());
let mut analyzer = UsagePatternAnalyzer::new(config, feature_extractor);
for i in 0..100 {
let event = create_test_usage_event("TestTrait", 1234567890 + (i * 3600));
analyzer.record_usage(event).expect("record_usage should succeed");
}
let patterns = analyzer.detect_seasonal_patterns("TestTrait");
assert!(patterns.is_ok());
let patterns = patterns.expect("expected valid value");
assert!(patterns.len() >= 0); }
#[test]
fn test_usage_prediction() {
let config = UsagePatternConfig::default();
let feature_extractor = TraitFeatureExtractor::new(FeatureExtractionConfig::default());
let mut analyzer = UsagePatternAnalyzer::new(config, feature_extractor);
for i in 0..10 {
let event = create_test_usage_event("TestTrait", 1234567890 + (i * 3600));
analyzer.record_usage(event).expect("record_usage should succeed");
}
analyzer.analyze_temporal_patterns("TestTrait").expect("analyze_temporal_patterns should succeed");
let predictions = analyzer.predict_usage("TestTrait", 7);
assert!(predictions.is_ok());
let predictions = predictions.expect("expected valid value");
assert_eq!(predictions.len(), 7);
for prediction in predictions {
assert!(prediction >= 0.0);
}
}
#[test]
fn test_pattern_based_recommender() {
let config = UsagePatternConfig::default();
let feature_extractor = TraitFeatureExtractor::new(FeatureExtractionConfig::default());
let pattern_analyzer = UsagePatternAnalyzer::new(config.clone(), feature_extractor);
let mut recommender = PatternBasedRecommender::new(pattern_analyzer, config);
let context = create_test_trait_context();
let recommendations = recommender.recommend_based_on_patterns(&context);
assert!(recommendations.is_ok());
let recommendations = recommendations.expect("expected valid value");
assert!(recommendations.len() >= 0); }
#[test]
fn test_anomaly_detection() {
let config = UsagePatternConfig::default();
let feature_extractor = TraitFeatureExtractor::new(FeatureExtractionConfig::default());
let analyzer = UsagePatternAnalyzer::new(config, feature_extractor);
let event = create_test_usage_event("TestTrait", 1234567890);
let anomaly = analyzer.detect_anomaly(&event);
assert!(anomaly.is_ok());
let anomaly = anomaly.expect("expected valid value");
assert!(anomaly.is_none()); }
}
#[allow(non_snake_case)]
#[cfg(test)]
mod recommender_engine_tests {
use super::*;
#[test]
fn test_recommender_engine_creation() {
let config = RecommenderEngineConfig::default();
let engine = MLRecommendationEngine::new(config);
assert!(engine.is_ok());
}
#[test]
fn test_ensemble_weights_validation() {
let weights = EnsembleWeights::default();
let total = weights.similarity_weight + weights.collaborative_weight +
weights.neural_weight + weights.pattern_weight +
weights.clustering_weight + weights.content_weight;
assert!((total - 1.0).abs() < 1e-10);
}
#[test]
fn test_trait_database_operations() {
let mut db = TraitDatabase::new();
let trait_info = create_test_trait_info("TestTrait");
db.add_trait(trait_info.clone());
assert!(db.get_trait("TestTrait").is_some());
assert_eq!(db.get_trait("TestTrait").expect("get_trait should succeed").name, "TestTrait");
db.add_relationship("TestTrait", "RelatedTrait");
let related = db.get_related_traits("TestTrait");
assert!(related.contains(&"RelatedTrait".to_string()));
}
#[test]
fn test_cache_settings() {
let settings = CacheSettings::default();
assert!(settings.enable_recommendation_cache);
assert!(settings.enable_similarity_cache);
assert_eq!(settings.cache_ttl_seconds, 3600);
}
#[test]
fn test_performance_tuning_config() {
let config = PerformanceTuning::default();
assert!(config.enable_parallel_processing);
assert_eq!(config.max_concurrent_recommendations, 10);
assert_eq!(config.batch_size, 32);
}
#[test]
fn test_recommendation_stats() {
let stats = RecommendationStats::default();
assert_eq!(stats.total_requests, 0);
assert_eq!(stats.cache_hits, 0);
assert_eq!(stats.successful_recommendations, 0);
}
#[test]
fn test_training_data_structure() {
let training_data = TrainingData {
contexts: vec![create_test_trait_context()],
features: create_test_array2(10, 5),
user_trait_matrix: create_test_array2(5, 10),
trait_features: create_test_array2(10, 8),
trait_relationships: HashMap::new(),
usage_patterns: vec![create_test_usage_event("TestTrait", 1234567890)],
};
assert_eq!(training_data.contexts.len(), 1);
assert_eq!(training_data.features.nrows(), 10);
assert_eq!(training_data.usage_patterns.len(), 1);
}
#[test]
fn test_recommendation_generation() {
let config = RecommenderEngineConfig::default();
let engine = MLRecommendationEngine::new(config).expect("expected valid value");
let context = create_test_trait_context();
let recommendations = engine.recommend(&context, 5);
assert!(recommendations.is_ok() || recommendations.is_err());
}
#[test]
fn test_cosine_similarity_calculation() {
let config = RecommenderEngineConfig::default();
let engine = MLRecommendationEngine::new(config).expect("expected valid value");
let vec_a = array![1.0, 0.0, 0.0];
let vec_b = array![0.0, 1.0, 0.0];
let vec_c = array![1.0, 0.0, 0.0];
let sim_ab = engine.calculate_cosine_similarity(&vec_a, &vec_b);
let sim_ac = engine.calculate_cosine_similarity(&vec_a, &vec_c);
assert_eq!(sim_ab, 0.0); assert_eq!(sim_ac, 1.0); }
#[test]
fn test_cache_key_generation() {
let config = RecommenderEngineConfig::default();
let engine = MLRecommendationEngine::new(config).expect("expected valid value");
let context1 = create_test_trait_context();
let context2 = create_test_trait_context();
let key1 = engine.context_to_cache_key(&context1);
let key2 = engine.context_to_cache_key(&context2);
assert_eq!(key1, key2); }
#[test]
fn test_usage_event_recording() {
let config = RecommenderEngineConfig::default();
let engine = MLRecommendationEngine::new(config).expect("expected valid value");
let event = create_test_usage_event("TestTrait", 1234567890);
let result = engine.record_usage(event);
assert!(result.is_ok());
}
#[test]
fn test_trait_database_updates() {
let config = RecommenderEngineConfig::default();
let engine = MLRecommendationEngine::new(config).expect("expected valid value");
let trait_info = create_test_trait_info("NewTrait");
let result = engine.update_trait_database(trait_info);
assert!(result.is_ok());
}
}
#[allow(non_snake_case)]
#[cfg(test)]
mod integration_tests {
use super::*;
#[test]
fn test_end_to_end_recommendation_flow() {
let config = RecommenderEngineConfig::default();
let mut engine = MLRecommendationEngine::new(config).expect("expected valid value");
let trait_info = create_test_trait_info("Debug");
engine.update_trait_database(trait_info).expect("update_trait_database should succeed");
let event = create_test_usage_event("Debug", 1234567890);
engine.record_usage(event).expect("record_usage should succeed");
let context = create_test_trait_context();
let recommendations = engine.recommend(&context, 3);
assert!(recommendations.is_ok() || recommendations.is_err());
}
#[test]
fn test_multi_module_interaction() {
let ml_config = MLRecommendationConfig::default();
let neural_config = NeuralNetworkConfig::default();
let feature_config = FeatureExtractionConfig::default();
let pattern_config = UsagePatternConfig::default();
let neural_model = NeuralEmbeddingModel::new(neural_config);
assert!(neural_model.is_ok());
let feature_extractor = TraitFeatureExtractor::new(feature_config.clone());
let pattern_analyzer = UsagePatternAnalyzer::new(pattern_config.clone(), feature_extractor);
let similarity_model = TraitSimilarityModel::new(ml_config);
assert!(true); }
#[test]
fn test_error_handling_across_modules() {
let config = FeatureExtractionConfig::default();
let mut extractor = TraitFeatureExtractor::new(config);
let empty_context = TraitContext::default();
let result = extractor.extract_context_features(&empty_context);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_performance_with_large_data() {
let config = MLRecommendationConfig::default();
let similarity_model = TraitSimilarityModel::new(config);
let large_vec = Array1::from_iter((0..1000).map(|x| x as f64));
let other_vec = Array1::from_iter((0..1000).map(|x| (x * 2) as f64));
let start = SystemTime::now();
let similarity = similarity_model.calculate_cosine_similarity(&large_vec, &other_vec);
let duration = start.elapsed().unwrap_or_default();
assert!(duration.as_millis() < 100);
assert!(similarity >= -1.0 && similarity <= 1.0);
}
#[test]
fn test_concurrent_access() {
use std::sync::Arc;
use std::thread;
let config = RecommenderEngineConfig::default();
let engine = Arc::new(MLRecommendationEngine::new(config).expect("expected valid value"));
let mut handles = vec![];
for i in 0..5 {
let engine_clone = Arc::clone(&engine);
let handle = thread::spawn(move || {
let context = create_test_trait_context();
let stats = engine_clone.get_stats();
assert_eq!(stats.total_requests, 0); });
handles.push(handle);
}
for handle in handles {
handle.join().expect("join should succeed");
}
}
#[test]
fn test_memory_efficiency() {
let config = UsagePatternConfig::default();
let feature_extractor = TraitFeatureExtractor::new(FeatureExtractionConfig::default());
let mut analyzer = UsagePatternAnalyzer::new(config, feature_extractor);
for i in 0..1000 {
let event = create_test_usage_event("TestTrait", 1234567890 + i);
analyzer.record_usage(event).expect("record_usage should succeed");
}
assert!(analyzer.usage_history.len() <= 1000);
}
}
#[allow(non_snake_case)]
#[cfg(test)]
mod benchmark_tests {
use super::*;
#[test]
fn benchmark_feature_extraction() {
let config = FeatureExtractionConfig::default();
let mut extractor = TraitFeatureExtractor::new(config);
let context = create_test_trait_context();
let start = SystemTime::now();
for _ in 0..100 {
let _ = extractor.extract_context_features(&context);
}
let duration = start.elapsed().unwrap_or_default();
assert!(duration.as_millis() < 1000);
}
#[test]
fn benchmark_similarity_calculation() {
let config = MLRecommendationConfig::default();
let model = TraitSimilarityModel::new(config);
let vec_a = Array1::from_iter((0..100).map(|x| x as f64));
let vec_b = Array1::from_iter((0..100).map(|x| (x * 2) as f64));
let start = SystemTime::now();
for _ in 0..1000 {
let _ = model.calculate_cosine_similarity(&vec_a, &vec_b);
}
let duration = start.elapsed().unwrap_or_default();
assert!(duration.as_millis() < 500);
}
#[test]
fn benchmark_neural_forward_pass() {
let config = NeuralNetworkConfig::default();
let model = NeuralEmbeddingModel::new(config).expect("expected valid value");
let input = Array1::zeros(128);
let start = SystemTime::now();
for _ in 0..100 {
let _ = model.forward(&input);
}
let duration = start.elapsed().unwrap_or_default();
assert!(duration.as_millis() < 1000);
}
}
#[allow(non_snake_case)]
#[cfg(test)]
mod property_tests {
use super::*;
#[test]
fn property_cosine_similarity_bounds() {
let config = MLRecommendationConfig::default();
let model = TraitSimilarityModel::new(config);
for _ in 0..100 {
let vec_a = Array1::from_iter((0..10).map(|_| (rng().gen::<f64>() - 0.5) * 100.0));
let vec_b = Array1::from_iter((0..10).map(|_| (rng().gen::<f64>() - 0.5) * 100.0));
let similarity = model.calculate_cosine_similarity(&vec_a, &vec_b);
assert!(similarity >= -1.0 && similarity <= 1.0);
}
}
#[test]
fn property_distance_non_negativity() {
let config = MLRecommendationConfig::default();
let model = TraitSimilarityModel::new(config);
for _ in 0..100 {
let vec_a = Array1::from_iter((0..10).map(|_| rng().gen::<f64>() * 100.0));
let vec_b = Array1::from_iter((0..10).map(|_| rng().gen::<f64>() * 100.0));
let euclidean = model.calculate_euclidean_distance(&vec_a, &vec_b);
let manhattan = model.calculate_manhattan_distance(&vec_a, &vec_b);
assert!(euclidean >= 0.0);
assert!(manhattan >= 0.0);
}
}
#[test]
fn property_neural_output_finite() {
let config = NeuralNetworkConfig::default();
let model = NeuralEmbeddingModel::new(config).expect("expected valid value");
for _ in 0..50 {
let input = Array1::from_iter((0..128).map(|_| (rng().gen::<f64>() - 0.5) * 10.0));
let output = model.forward(&input).expect("forward should succeed");
for value in output.iter() {
assert!(value.is_finite());
}
}
}
}