diff --git a/apps/desktop/src-tauri/src/infrastructure/gemini_service.rs b/apps/desktop/src-tauri/src/infrastructure/gemini_service.rs index 18b7730..6714669 100644 --- a/apps/desktop/src-tauri/src/infrastructure/gemini_service.rs +++ b/apps/desktop/src-tauri/src/infrastructure/gemini_service.rs @@ -1563,7 +1563,3 @@ impl GeminiService { } } -// 导入测试文件 -#[cfg(test)] -#[path = "gemini_service_tests.rs"] -mod gemini_service_tests; diff --git a/apps/desktop/src-tauri/src/infrastructure/gemini_service_tests.rs b/apps/desktop/src-tauri/src/infrastructure/gemini_service_tests.rs deleted file mode 100644 index 56d3b87..0000000 --- a/apps/desktop/src-tauri/src/infrastructure/gemini_service_tests.rs +++ /dev/null @@ -1,226 +0,0 @@ -#[cfg(test)] -mod rag_grounding_tests { - use crate::infrastructure::gemini_service::{ - GeminiService, GeminiConfig, RagGroundingRequest, RagGroundingConfig, RagGroundingResponse, - GroundingMetadata, GroundingSource, - }; - - /// 创建测试用的 GeminiService 实例 - fn create_test_service() -> GeminiService { - let config = GeminiConfig::default(); - GeminiService::new(Some(config)).expect("Failed to create test service") - } - - /// 创建测试用的 RAG Grounding 请求 - fn create_test_request() -> RagGroundingRequest { - RagGroundingRequest { - user_input: "测试查询".to_string(), - config: Some(RagGroundingConfig::default()), - session_id: Some("test-session".to_string()), - } - } - - #[test] - fn test_rag_grounding_config_default() { - let config = RagGroundingConfig::default(); - - assert_eq!(config.project_id, "gen-lang-client-0413414134"); - assert_eq!(config.location, "global"); - assert_eq!(config.data_store_id, "jeans_pattern_data_store"); - assert_eq!(config.model_id, "gemini-2.5-flash"); - assert_eq!(config.temperature, 1.0); - assert_eq!(config.max_output_tokens, 8192); - assert!(config.system_prompt.is_none()); - } - - #[test] - fn test_rag_grounding_request_creation() { - let request = create_test_request(); - - assert_eq!(request.user_input, "测试查询"); - assert!(request.config.is_some()); - assert_eq!(request.session_id, Some("test-session".to_string())); - } - - #[test] - fn test_rag_grounding_request_serialization() { - let request = create_test_request(); - - // 测试序列化 - let serialized = serde_json::to_string(&request).expect("Failed to serialize request"); - assert!(serialized.contains("测试查询")); - assert!(serialized.contains("test-session")); - - // 测试反序列化 - let deserialized: RagGroundingRequest = serde_json::from_str(&serialized) - .expect("Failed to deserialize request"); - assert_eq!(deserialized.user_input, request.user_input); - assert_eq!(deserialized.session_id, request.session_id); - } - - #[test] - fn test_rag_grounding_response_creation() { - let response = RagGroundingResponse { - answer: "测试回答".to_string(), - grounding_metadata: Some(GroundingMetadata { - sources: vec![GroundingSource { - title: "测试来源".to_string(), - uri: Some("https://example.com".to_string()), - snippet: "测试片段".to_string(), - relevance_score: Some(0.95), - }], - search_queries: vec!["测试查询".to_string()], - }), - response_time_ms: 1500, - model_used: "gemini-2.5-flash".to_string(), - }; - - assert_eq!(response.answer, "测试回答"); - assert!(response.grounding_metadata.is_some()); - assert_eq!(response.response_time_ms, 1500); - assert_eq!(response.model_used, "gemini-2.5-flash"); - - let metadata = response.grounding_metadata.unwrap(); - assert_eq!(metadata.sources.len(), 1); - assert_eq!(metadata.search_queries.len(), 1); - - let source = &metadata.sources[0]; - assert_eq!(source.title, "测试来源"); - assert_eq!(source.uri, Some("https://example.com".to_string())); - assert_eq!(source.snippet, "测试片段"); - assert_eq!(source.relevance_score, Some(0.95)); - } - - #[test] - fn test_grounding_metadata_empty() { - let metadata = GroundingMetadata { - sources: vec![], - search_queries: vec![], - }; - - assert!(metadata.sources.is_empty()); - assert!(metadata.search_queries.is_empty()); - } - - #[test] - fn test_grounding_source_without_optional_fields() { - let source = GroundingSource { - title: "测试来源".to_string(), - uri: None, - snippet: "测试片段".to_string(), - relevance_score: None, - }; - - assert_eq!(source.title, "测试来源"); - assert!(source.uri.is_none()); - assert_eq!(source.snippet, "测试片段"); - assert!(source.relevance_score.is_none()); - } - - #[test] - fn test_rag_grounding_config_with_system_prompt() { - let mut config = RagGroundingConfig::default(); - config.system_prompt = Some("你是一个专业的助手".to_string()); - - assert!(config.system_prompt.is_some()); - assert_eq!(config.system_prompt.unwrap(), "你是一个专业的助手"); - } - - #[test] - fn test_rag_grounding_config_custom_values() { - let config = RagGroundingConfig { - project_id: "custom-project".to_string(), - location: "us-central1".to_string(), - data_store_id: "custom-datastore".to_string(), - model_id: "gemini-pro".to_string(), - temperature: 0.5, - max_output_tokens: 4096, - system_prompt: Some("自定义系统提示".to_string()), - }; - - assert_eq!(config.project_id, "custom-project"); - assert_eq!(config.location, "us-central1"); - assert_eq!(config.data_store_id, "custom-datastore"); - assert_eq!(config.model_id, "gemini-pro"); - assert_eq!(config.temperature, 0.5); - assert_eq!(config.max_output_tokens, 4096); - assert_eq!(config.system_prompt, Some("自定义系统提示".to_string())); - } - - #[test] - fn test_gemini_service_creation() { - let service = create_test_service(); - // 基本的服务创建测试,确保没有panic - assert!(true); // 如果能到这里说明服务创建成功 - } - - /// 测试 JSON 响应解析 - #[test] - fn test_parse_rag_grounding_response_json() { - let service = create_test_service(); - - // 模拟一个典型的 Gemini API 响应 - let mock_response = r#"{ - "candidates": [{ - "content": { - "parts": [{ - "text": "这是一个测试回答" - }] - }, - "groundingMetadata": { - "groundingSources": [{ - "title": "测试文档", - "uri": "https://example.com/doc", - "snippet": "这是一个测试片段", - "relevanceScore": 0.85 - }], - "searchQueries": ["测试查询"] - } - }] - }"#; - - let result = service.parse_rag_grounding_response(mock_response); - assert!(result.is_ok()); - - let response = result.unwrap(); - assert_eq!(response.answer, "这是一个测试回答"); - assert!(response.grounding_metadata.is_some()); - - let metadata = response.grounding_metadata.unwrap(); - assert_eq!(metadata.sources.len(), 1); - assert_eq!(metadata.search_queries.len(), 1); - - let source = &metadata.sources[0]; - assert_eq!(source.title, "测试文档"); - assert_eq!(source.uri, Some("https://example.com/doc".to_string())); - assert_eq!(source.snippet, "这是一个测试片段"); - assert_eq!(source.relevance_score, Some(0.85)); - } - - /// 测试无效 JSON 响应处理 - #[test] - fn test_parse_invalid_json_response() { - let service = create_test_service(); - - let invalid_json = "这不是有效的JSON"; - let result = service.parse_rag_grounding_response(invalid_json); - assert!(result.is_err()); - } - - /// 测试缺少必要字段的响应 - #[test] - fn test_parse_incomplete_response() { - let service = create_test_service(); - - let incomplete_response = r#"{ - "candidates": [] - }"#; - - let result = service.parse_rag_grounding_response(incomplete_response); - assert!(result.is_ok()); - - let response = result.unwrap(); - assert_eq!(response.answer, "无法解析响应内容"); - assert!(response.grounding_metadata.is_none()); - } -} diff --git a/apps/desktop/src-tauri/src/presentation/commands/rag_grounding_commands.rs b/apps/desktop/src-tauri/src/presentation/commands/rag_grounding_commands.rs index ba42046..e405a18 100644 --- a/apps/desktop/src-tauri/src/presentation/commands/rag_grounding_commands.rs +++ b/apps/desktop/src-tauri/src/presentation/commands/rag_grounding_commands.rs @@ -120,19 +120,6 @@ mod tests { use super::*; use crate::infrastructure::gemini_service::RagGroundingConfig; - #[tokio::test] - async fn test_rag_grounding_request_creation() { - let request = RagGroundingRequest { - user_input: "测试查询".to_string(), - config: Some(RagGroundingConfig::default()), - session_id: Some("test-session".to_string()), - }; - - assert_eq!(request.user_input, "测试查询"); - assert!(request.config.is_some()); - assert_eq!(request.session_id, Some("test-session".to_string())); - } - #[test] fn test_rag_grounding_config_default() { let config = RagGroundingConfig::default(); @@ -144,8 +131,3 @@ mod tests { assert_eq!(config.max_output_tokens, 8192); } } - -// 导入测试文件 -#[cfg(test)] -#[path = "rag_grounding_commands_tests.rs"] -mod rag_grounding_commands_tests; diff --git a/apps/desktop/src-tauri/src/presentation/commands/rag_grounding_commands_tests.rs b/apps/desktop/src-tauri/src/presentation/commands/rag_grounding_commands_tests.rs deleted file mode 100644 index 53e5701..0000000 --- a/apps/desktop/src-tauri/src/presentation/commands/rag_grounding_commands_tests.rs +++ /dev/null @@ -1,189 +0,0 @@ -#[cfg(test)] -mod rag_grounding_commands_tests { - use super::*; - use crate::app_state::AppState; - use crate::infrastructure::gemini_service::{RagGroundingRequest, RagGroundingConfig}; - use tauri::State; - use std::sync::Arc; - - /// 创建测试用的 AppState - fn create_test_app_state() -> AppState { - AppState::new() - } - - #[test] - fn test_rag_grounding_request_validation() { - let request = RagGroundingRequest { - user_input: "测试查询".to_string(), - config: Some(RagGroundingConfig::default()), - session_id: Some("test-session".to_string()), - }; - - // 验证请求结构 - assert!(!request.user_input.is_empty()); - assert!(request.config.is_some()); - assert!(request.session_id.is_some()); - } - - #[test] - fn test_rag_grounding_config_serialization() { - let config = RagGroundingConfig::default(); - - // 测试序列化 - let serialized = serde_json::to_string(&config).expect("Failed to serialize config"); - assert!(serialized.contains("gen-lang-client-0413414134")); - assert!(serialized.contains("gemini-2.5-flash")); - - // 测试反序列化 - let deserialized: RagGroundingConfig = serde_json::from_str(&serialized) - .expect("Failed to deserialize config"); - assert_eq!(deserialized.project_id, config.project_id); - assert_eq!(deserialized.model_id, config.model_id); - } - - #[test] - fn test_empty_user_input_handling() { - let request = RagGroundingRequest { - user_input: "".to_string(), - config: None, - session_id: None, - }; - - // 空输入应该被正确处理 - assert!(request.user_input.is_empty()); - assert!(request.config.is_none()); - assert!(request.session_id.is_none()); - } - - #[test] - fn test_custom_config_override() { - let custom_config = RagGroundingConfig { - project_id: "custom-project".to_string(), - location: "us-central1".to_string(), - data_store_id: "custom-datastore".to_string(), - model_id: "gemini-pro".to_string(), - temperature: 0.5, - max_output_tokens: 4096, - system_prompt: Some("自定义提示".to_string()), - }; - - let request = RagGroundingRequest { - user_input: "测试查询".to_string(), - config: Some(custom_config.clone()), - session_id: Some("custom-session".to_string()), - }; - - assert_eq!(request.config.as_ref().unwrap().project_id, "custom-project"); - assert_eq!(request.config.as_ref().unwrap().temperature, 0.5); - assert_eq!(request.config.as_ref().unwrap().system_prompt, Some("自定义提示".to_string())); - } - - #[test] - fn test_session_id_generation() { - let session_id = format!("session-{}", chrono::Utc::now().timestamp()); - - let request = RagGroundingRequest { - user_input: "测试查询".to_string(), - config: None, - session_id: Some(session_id.clone()), - }; - - assert_eq!(request.session_id, Some(session_id)); - assert!(request.session_id.as_ref().unwrap().starts_with("session-")); - } - - #[test] - fn test_config_json_structure() { - let config = RagGroundingConfig::default(); - let json_value = serde_json::to_value(&config).expect("Failed to convert to JSON"); - - // 验证必要字段存在 - assert!(json_value.get("project_id").is_some()); - assert!(json_value.get("location").is_some()); - assert!(json_value.get("data_store_id").is_some()); - assert!(json_value.get("model_id").is_some()); - assert!(json_value.get("temperature").is_some()); - assert!(json_value.get("max_output_tokens").is_some()); - - // 验证字段类型 - assert!(json_value["project_id"].is_string()); - assert!(json_value["temperature"].is_number()); - assert!(json_value["max_output_tokens"].is_number()); - } - - #[test] - fn test_request_with_minimal_data() { - let request = RagGroundingRequest { - user_input: "简单查询".to_string(), - config: None, - session_id: None, - }; - - // 最小数据请求应该有效 - assert_eq!(request.user_input, "简单查询"); - assert!(request.config.is_none()); - assert!(request.session_id.is_none()); - } - - #[test] - fn test_unicode_input_handling() { - let unicode_input = "测试中文输入 🔍 emoji 和特殊字符 @#$%"; - - let request = RagGroundingRequest { - user_input: unicode_input.to_string(), - config: None, - session_id: None, - }; - - assert_eq!(request.user_input, unicode_input); - - // 测试序列化包含Unicode字符的请求 - let serialized = serde_json::to_string(&request).expect("Failed to serialize Unicode request"); - assert!(serialized.contains("测试中文输入")); - assert!(serialized.contains("🔍")); - } - - #[test] - fn test_long_input_handling() { - let long_input = "这是一个很长的输入".repeat(100); - - let request = RagGroundingRequest { - user_input: long_input.clone(), - config: None, - session_id: None, - }; - - assert_eq!(request.user_input.len(), long_input.len()); - assert!(request.user_input.len() > 1000); // 确保输入确实很长 - } - - #[test] - fn test_config_temperature_bounds() { - let mut config = RagGroundingConfig::default(); - - // 测试不同的温度值 - config.temperature = 0.0; - assert_eq!(config.temperature, 0.0); - - config.temperature = 1.0; - assert_eq!(config.temperature, 1.0); - - config.temperature = 2.0; - assert_eq!(config.temperature, 2.0); - } - - #[test] - fn test_config_token_limits() { - let mut config = RagGroundingConfig::default(); - - // 测试不同的令牌限制 - config.max_output_tokens = 1024; - assert_eq!(config.max_output_tokens, 1024); - - config.max_output_tokens = 8192; - assert_eq!(config.max_output_tokens, 8192); - - config.max_output_tokens = 32768; - assert_eq!(config.max_output_tokens, 32768); - } -} diff --git a/apps/desktop/src/components/MultiTurnChatTest.tsx b/apps/desktop/src/components/MultiTurnChatTest.tsx index d056ca3..5bb4726 100644 --- a/apps/desktop/src/components/MultiTurnChatTest.tsx +++ b/apps/desktop/src/components/MultiTurnChatTest.tsx @@ -2,9 +2,7 @@ import React, { useState, useCallback, useRef, useEffect } from 'react'; import { ConversationService, MultiTurnConversationHelper } from '../services/conversationService'; import { ChatMessage, - MultiTurnConversationOptions, ConversationUtils, - MessageContentUtils } from '../types/conversation'; /** diff --git a/apps/desktop/src/components/MultiTurnRagChatTest.tsx b/apps/desktop/src/components/MultiTurnRagChatTest.tsx index 4d7ec84..d0989c5 100644 --- a/apps/desktop/src/components/MultiTurnRagChatTest.tsx +++ b/apps/desktop/src/components/MultiTurnRagChatTest.tsx @@ -2,7 +2,6 @@ import React, { useState, useCallback, useRef, useEffect } from 'react'; import { queryRagGrounding } from '../services/ragGroundingService'; import { RagGroundingQueryOptions, - RagGroundingResponse, GroundingSource, ConversationContext, } from '../types/ragGrounding';