//! NAC AI估值系统集成测试 //! //! 测试所有模块的集成和端到端功能 use nac_ai_valuation::*; use rust_decimal::Decimal; use std::collections::HashMap; /// 创建测试资产 fn create_test_asset() -> Asset { Asset::new( "test_asset_001".to_string(), AssetType::RealEstate, "GNACS-RE-001".to_string(), "Manhattan Office Building".to_string(), Decimal::new(50_000_000, 0), "USD".to_string(), ) } /// 创建测试估值结果 fn create_test_valuation_result() -> FinalValuationResult { FinalValuationResult { valuation_xtzh: Decimal::new(500_000, 0), confidence: 0.85, model_results: vec![], weights: HashMap::new(), is_anomaly: false, anomaly_report: None, divergence_report: "Test divergence report".to_string(), requires_human_review: false, } } #[test] fn test_asset_creation() { let asset = create_test_asset(); assert_eq!(asset.id, "test_asset_001"); assert_eq!(asset.asset_type, AssetType::RealEstate); assert_eq!(asset.gnacs_code, "GNACS-RE-001"); assert_eq!(asset.base_valuation_local, Decimal::new(50_000_000, 0)); } #[test] fn test_jurisdiction_info() { let us_info = Jurisdiction::US.info(); assert_eq!(us_info.code, Jurisdiction::US); assert!(us_info.corporate_tax_rate > 0.0); let china_info = Jurisdiction::China.info(); assert_eq!(china_info.code, Jurisdiction::China); assert!(china_info.corporate_tax_rate > 0.0); } #[test] fn test_international_agreement_info() { let wto_info = InternationalAgreement::WTO.info(); assert_eq!(wto_info.name, "世界贸易组织"); let rcep_info = InternationalAgreement::RCEP.info(); assert_eq!(rcep_info.name, "区域全面经济伙伴关系协定"); } #[test] fn test_valuation_history() { let mut history = ValuationHistory::new(100); let entry = ValuationHistoryEntry::new( "test_asset_001".to_string(), Jurisdiction::US, InternationalAgreement::WTO, create_test_valuation_result(), ); history.add(entry.clone()).unwrap(); let entries = history.get_by_asset("test_asset_001"); assert_eq!(entries.len(), 1); assert_eq!(entries[0].asset_id, "test_asset_001"); } #[test] fn test_trend_analysis() { let entries = vec![ ValuationHistoryEntry::new( "test_asset_001".to_string(), Jurisdiction::US, InternationalAgreement::WTO, FinalValuationResult { valuation_xtzh: Decimal::new(1_000_000, 0), confidence: 0.85, model_results: vec![], weights: HashMap::new(), is_anomaly: false, anomaly_report: None, divergence_report: "Test".to_string(), requires_human_review: false, }, ), ValuationHistoryEntry::new( "test_asset_001".to_string(), Jurisdiction::US, InternationalAgreement::WTO, FinalValuationResult { valuation_xtzh: Decimal::new(1_100_000, 0), confidence: 0.88, model_results: vec![], weights: HashMap::new(), is_anomaly: false, anomaly_report: None, divergence_report: "Test".to_string(), requires_human_review: false, }, ), ValuationHistoryEntry::new( "test_asset_001".to_string(), Jurisdiction::US, InternationalAgreement::WTO, FinalValuationResult { valuation_xtzh: Decimal::new(1_200_000, 0), confidence: 0.90, model_results: vec![], weights: HashMap::new(), is_anomaly: false, anomaly_report: None, divergence_report: "Test".to_string(), requires_human_review: false, }, ), ]; let trend = TrendAnalyzer::analyze(&entries).unwrap(); assert_eq!(trend.data_points, 3); assert!(trend.change_rate > 0.0); // 上升趋势 // 趋势可能是Upward或Volatile,取决于标准差 assert!(trend.trend_direction == TrendDirection::Upward || trend.trend_direction == TrendDirection::Volatile); } #[test] fn test_validation_rules() { let validator = ValuationValidator::with_default_rules(); let result = FinalValuationResult { valuation_xtzh: Decimal::new(1_000_000, 0), confidence: 0.85, model_results: vec![], weights: HashMap::new(), is_anomaly: false, anomaly_report: None, divergence_report: "Test".to_string(), requires_human_review: false, }; let validation_results = validator.validate(&result); assert!(!validation_results.is_empty()); // 应该通过所有默认验证 let all_passed = validator.validate_all(&result); assert!(all_passed); } #[test] fn test_validation_failure() { let validator = ValuationValidator::with_default_rules(); // 置信度过低的结果 let result = FinalValuationResult { valuation_xtzh: Decimal::new(1_000_000, 0), confidence: 0.3, // 低于默认的0.5 model_results: vec![], weights: HashMap::new(), is_anomaly: false, anomaly_report: None, divergence_report: "Test".to_string(), requires_human_review: false, }; let all_passed = validator.validate_all(&result); assert!(!all_passed); } #[test] fn test_accuracy_evaluation() { let metrics = AccuracyEvaluator::evaluate( Decimal::new(1_000_000, 0), Decimal::new(1_100_000, 0), ); assert_eq!(metrics.estimated, Decimal::new(1_000_000, 0)); assert_eq!(metrics.actual, Decimal::new(1_100_000, 0)); assert!(metrics.relative_error > 9.0 && metrics.relative_error < 10.0); assert!(metrics.accuracy > 90.0); } #[test] fn test_batch_accuracy_evaluation() { let pairs = vec![ (Decimal::new(1_000_000, 0), Decimal::new(1_100_000, 0)), (Decimal::new(2_000_000, 0), Decimal::new(2_050_000, 0)), (Decimal::new(3_000_000, 0), Decimal::new(2_900_000, 0)), ]; let batch_metrics = AccuracyEvaluator::evaluate_batch(pairs); assert_eq!(batch_metrics.total_samples, 3); assert!(batch_metrics.avg_accuracy > 90.0); } #[test] fn test_divergence_analysis() { use chrono::Utc; let model_results = vec![ AIValuationResult { provider: AIProvider::ChatGPT, valuation_xtzh: Decimal::new(1_000_000, 0), confidence: 0.85, reasoning: "ChatGPT reasoning".to_string(), timestamp: Utc::now(), }, AIValuationResult { provider: AIProvider::DeepSeek, valuation_xtzh: Decimal::new(1_100_000, 0), confidence: 0.88, reasoning: "DeepSeek reasoning".to_string(), timestamp: Utc::now(), }, AIValuationResult { provider: AIProvider::DouBao, valuation_xtzh: Decimal::new(1_050_000, 0), confidence: 0.82, reasoning: "DouBao reasoning".to_string(), timestamp: Utc::now(), }, ]; let analysis = DivergenceAnalyzer::analyze(&model_results); assert_eq!(analysis.model_count, 3); assert_eq!(analysis.min_valuation, Decimal::new(1_000_000, 0)); assert_eq!(analysis.max_valuation, Decimal::new(1_100_000, 0)); assert!(analysis.divergence_rate < 15.0); assert!(analysis.consistency_score > 85.0); } #[test] fn test_divergence_with_outlier() { use chrono::Utc; let model_results = vec![ AIValuationResult { provider: AIProvider::ChatGPT, valuation_xtzh: Decimal::new(1_000_000, 0), confidence: 0.85, reasoning: "ChatGPT reasoning".to_string(), timestamp: Utc::now(), }, AIValuationResult { provider: AIProvider::DeepSeek, valuation_xtzh: Decimal::new(1_050_000, 0), confidence: 0.88, reasoning: "DeepSeek reasoning".to_string(), timestamp: Utc::now(), }, AIValuationResult { provider: AIProvider::DouBao, valuation_xtzh: Decimal::new(2_000_000, 0), // 异常值 confidence: 0.82, reasoning: "DouBao reasoning".to_string(), timestamp: Utc::now(), }, ]; let analysis = DivergenceAnalyzer::analyze(&model_results); assert_eq!(analysis.model_count, 3); assert!(analysis.divergence_rate > 50.0); assert!(!analysis.outliers.is_empty()); assert!(analysis.outliers.contains(&AIProvider::DouBao)); } #[test] fn test_optimization_suggestions() { use chrono::Utc; let model_results = vec![ AIValuationResult { provider: AIProvider::ChatGPT, valuation_xtzh: Decimal::new(1_000_000, 0), confidence: 0.85, reasoning: "Test".to_string(), timestamp: Utc::now(), }, AIValuationResult { provider: AIProvider::DeepSeek, valuation_xtzh: Decimal::new(2_000_000, 0), confidence: 0.88, reasoning: "Test".to_string(), timestamp: Utc::now(), }, ]; let result = FinalValuationResult { valuation_xtzh: Decimal::new(1_500_000, 0), confidence: 0.60, model_results: model_results.clone(), weights: HashMap::new(), is_anomaly: false, anomaly_report: None, divergence_report: "Test".to_string(), requires_human_review: false, }; let divergence = DivergenceAnalyzer::analyze(&model_results); let suggestions = ModelOptimizer::generate_suggestions(&result, &divergence); assert!(!suggestions.is_empty()); } #[test] fn test_cache_operations() { let cache = ValuationCache::new(10); let result = create_test_valuation_result(); // 设置缓存 cache.set( "test_asset_001", Jurisdiction::US, InternationalAgreement::WTO, result.clone(), ); // 获取缓存 let cached = cache.get( "test_asset_001", Jurisdiction::US, InternationalAgreement::WTO, ); assert!(cached.is_some()); assert_eq!(cached.unwrap().valuation_xtzh, result.valuation_xtzh); // 统计 let stats = cache.stats(); assert_eq!(stats.total_entries, 1); assert_eq!(stats.total_accesses, 1); } #[test] fn test_cache_expiry() { let cache = ValuationCache::new(10); let result = create_test_valuation_result(); cache.set( "test_asset_001", Jurisdiction::US, InternationalAgreement::WTO, result, ); // 清除过期缓存(刚设置的不会过期) cache.clear_expired(); let stats = cache.stats(); assert_eq!(stats.total_entries, 1); assert_eq!(stats.expired_entries, 0); } #[test] fn test_realtime_data_source() { let data_source = RealtimeDataSource::new(); assert_eq!(data_source.xtzh_price_usd, Decimal::new(100, 0)); assert!(!data_source.is_stale()); } #[test] fn test_final_valuation_result_report() { let result = create_test_valuation_result(); let report = result.generate_report(); assert!(report.contains("NAC AI资产估值报告")); assert!(report.contains("500000 XTZH")); assert!(report.contains("85.0%")); } #[test] fn test_final_valuation_result_json() { let result = create_test_valuation_result(); let json = result.to_json().unwrap(); assert!(json.contains("valuation_xtzh")); assert!(json.contains("confidence")); assert!(json.contains("500000")); } #[test] fn test_data_export_json() { use std::path::Path; let entries = vec![ ValuationHistoryEntry::new( "test_asset_001".to_string(), Jurisdiction::US, InternationalAgreement::WTO, create_test_valuation_result(), ), ]; let path = Path::new("/tmp/test_valuation_export.json"); let result = DataExporter::export_json(&entries, path); assert!(result.is_ok()); // 验证文件存在 assert!(path.exists()); } #[test] fn test_data_export_csv() { use std::path::Path; let entries = vec![ ValuationHistoryEntry::new( "test_asset_001".to_string(), Jurisdiction::US, InternationalAgreement::WTO, create_test_valuation_result(), ), ]; let path = Path::new("/tmp/test_valuation_export.csv"); let result = DataExporter::export_csv(&entries, path); assert!(result.is_ok()); // 验证文件存在 assert!(path.exists()); } #[test] fn test_data_export_markdown() { use std::path::Path; let entries = vec![ ValuationHistoryEntry::new( "test_asset_001".to_string(), Jurisdiction::US, InternationalAgreement::WTO, create_test_valuation_result(), ), ]; let trend = TrendAnalyzer::analyze(&entries).unwrap(); let path = Path::new("/tmp/test_valuation_export.md"); let result = DataExporter::export_markdown(&entries, &trend, path); assert!(result.is_ok()); // 验证文件存在 assert!(path.exists()); } #[tokio::test] #[ignore] // 需要真实的API密钥 async fn test_full_valuation_flow() { // 创建估值引擎 let engine = ValuationEngine::new( std::env::var("CHATGPT_API_KEY").unwrap_or("test_key".to_string()), std::env::var("DEEPSEEK_API_KEY").unwrap_or("test_key".to_string()), std::env::var("DOUBAO_API_KEY").unwrap_or("test_key".to_string()), ValuationEngineConfig::default(), ).unwrap(); // 创建资产 let asset = create_test_asset(); // 执行估值 let result = engine.appraise( &asset, Jurisdiction::US, InternationalAgreement::WTO, ).await; // 验证结果 if let Ok(result) = result { assert!(result.valuation_xtzh > Decimal::ZERO); assert!(result.confidence >= 0.0 && result.confidence <= 1.0); assert!(!result.model_results.is_empty()); } } #[test] fn test_all_asset_types() { let types = vec![ AssetType::RealEstate, AssetType::Commodity, AssetType::FinancialAsset, AssetType::DigitalAsset, AssetType::IntellectualProperty, AssetType::ArtCollectible, AssetType::Movable, AssetType::Receivable, AssetType::Infrastructure, AssetType::NaturalResource, AssetType::ESGAsset, AssetType::Other, ]; assert_eq!(types.len(), 12); } #[test] fn test_all_jurisdictions() { let jurisdictions = vec![ Jurisdiction::US, Jurisdiction::EU, Jurisdiction::China, Jurisdiction::HongKong, Jurisdiction::SG, Jurisdiction::UK, Jurisdiction::JP, Jurisdiction::ME, ]; assert_eq!(jurisdictions.len(), 8); // 验证每个辖区都有有效信息 for jurisdiction in jurisdictions { let info = jurisdiction.info(); assert!(info.corporate_tax_rate >= 0.0); assert!(info.corporate_tax_rate >= 0.0); } } #[test] fn test_all_agreements() { let agreements = vec![ InternationalAgreement::EU, InternationalAgreement::WTO, InternationalAgreement::SCO, InternationalAgreement::RCEP, InternationalAgreement::CPTPP, InternationalAgreement::USMCA, InternationalAgreement::AfCFTA, InternationalAgreement::None, ]; assert_eq!(agreements.len(), 8); // 验证每个协定都有有效信息 for agreement in agreements { let info = agreement.info(); assert!(!info.name.is_empty()); } }