Files
qiming/qiming-rcoder/crates/agent_runner/src/testing/fixtures.rs
2026-06-01 13:54:52 +08:00

227 lines
6.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 测试 Fixtures
//!
//! 提供测试用的构造器和辅助工具
use crate::proxy_agent::AgentRequest;
use agent_abstraction::PromptMessage;
use shared_types::{Attachment, ServiceType};
use std::path::PathBuf;
/// 测试请求构造器
///
/// # Example
///
/// ```rust
/// use agent_runner::testing::fixtures::TestRequestBuilder;
///
/// // 创建基础测试请求
/// let (req, resp_rx) = TestRequestBuilder::new()
/// .project_id("test-project")
/// .content("Hello, Agent!")
/// .build();
/// ```
pub struct TestRequestBuilder {
project_id: String,
content: String,
request_id: String,
attachments: Vec<Attachment>,
session_id: Option<String>,
project_path: Option<PathBuf>,
}
impl Default for TestRequestBuilder {
fn default() -> Self {
Self::new()
}
}
impl TestRequestBuilder {
/// 创建新的测试请求构造器
pub fn new() -> Self {
Self {
project_id: "test-project".to_string(),
content: "Hello, Agent!".to_string(),
request_id: uuid::Uuid::new_v4().to_string().replace("-", ""),
attachments: vec![],
session_id: None,
project_path: None,
}
}
/// 设置 project_id
pub fn project_id(mut self, id: &str) -> Self {
self.project_id = id.to_string();
self
}
/// 设置请求内容
pub fn content(mut self, content: &str) -> Self {
self.content = content.to_string();
self
}
/// 设置 request_id
pub fn request_id(mut self, request_id: &str) -> Self {
self.request_id = request_id.to_string();
self
}
/// 设置 session_id
pub fn session_id(mut self, session_id: &str) -> Self {
self.session_id = Some(session_id.to_string());
self
}
/// 设置项目路径
pub fn project_path(mut self, path: &str) -> Self {
self.project_path = Some(PathBuf::from(path));
self
}
/// 添加附件
pub fn add_attachment(mut self, attachment: Attachment) -> Self {
self.attachments.push(attachment);
self
}
/// 构建 PromptMessage用于测试验证
///
/// 返回构建的 PromptMessage可以直接访问字段进行断言验证
pub fn build_prompt_message(&self) -> PromptMessage {
PromptMessage {
content: self.content.clone(),
project_id: self.project_id.clone(),
project_path: self
.project_path
.clone()
.unwrap_or_else(|| PathBuf::from("/tmp/test")),
session_id: self.session_id.clone(),
request_id: self.request_id.clone(),
attachments: self.attachments.clone(),
data_source_attachments: vec![],
service_type: ServiceType::RCoder,
system_prompt_override: None,
user_prompt_template_override: None,
agent_config_override: None,
}
}
/// 构建测试请求
pub fn build(
self,
) -> (
AgentRequest,
tokio::sync::oneshot::Receiver<crate::model::ChatPromptResponse>,
) {
let prompt_message = self.build_prompt_message();
AgentRequest::new(prompt_message, None)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_test_request_builder_default() {
let builder = TestRequestBuilder::new();
let prompt = builder.build_prompt_message();
// 验证默认值
assert_eq!(prompt.project_id, "test-project");
assert_eq!(prompt.content, "Hello, Agent!");
assert!(!prompt.request_id.is_empty(), "request_id 应该自动生成");
assert_eq!(prompt.project_path, PathBuf::from("/tmp/test"));
assert!(prompt.session_id.is_none());
assert!(prompt.attachments.is_empty());
assert_eq!(prompt.service_type, ServiceType::RCoder);
}
#[test]
fn test_test_request_builder_with_project_id() {
let prompt = TestRequestBuilder::new()
.project_id("custom-project")
.build_prompt_message();
assert_eq!(prompt.project_id, "custom-project");
}
#[test]
fn test_test_request_builder_with_content() {
let prompt = TestRequestBuilder::new()
.content("Custom content")
.build_prompt_message();
assert_eq!(prompt.content, "Custom content");
}
#[test]
fn test_test_request_builder_with_session_id() {
let prompt = TestRequestBuilder::new()
.session_id("test-session-123")
.build_prompt_message();
assert_eq!(prompt.session_id, Some("test-session-123".to_string()));
}
#[test]
fn test_test_request_builder_with_request_id() {
let prompt = TestRequestBuilder::new()
.request_id("custom-request-id")
.build_prompt_message();
assert_eq!(prompt.request_id, "custom-request-id");
}
#[test]
fn test_test_request_builder_with_project_path() {
let prompt = TestRequestBuilder::new()
.project_path("/home/user/project")
.build_prompt_message();
assert_eq!(prompt.project_path, PathBuf::from("/home/user/project"));
}
#[test]
fn test_test_request_builder_chain() {
// 验证链式调用和所有字段设置
let prompt = TestRequestBuilder::new()
.project_id("my-project")
.content("Test content")
.request_id("custom-request-id")
.session_id("session-456")
.project_path("/home/user/project")
.build_prompt_message();
assert_eq!(prompt.project_id, "my-project");
assert_eq!(prompt.content, "Test content");
assert_eq!(prompt.request_id, "custom-request-id");
assert_eq!(prompt.session_id, Some("session-456".to_string()));
assert_eq!(prompt.project_path, PathBuf::from("/home/user/project"));
}
#[test]
fn test_test_request_builder_build_returns_receiver() {
// 验证 build() 返回的接收器可用
let (_req, mut rx) = TestRequestBuilder::new().build();
// 验证接收器尚未收到消息
assert!(rx.try_recv().is_err(), "接收器应该为空");
}
#[test]
fn test_test_request_builder_request_id_auto_generated() {
// 验证每次构建生成不同的 request_id
let builder1 = TestRequestBuilder::new();
let builder2 = TestRequestBuilder::new();
let prompt1 = builder1.build_prompt_message();
let prompt2 = builder2.build_prompt_message();
assert_ne!(
prompt1.request_id, prompt2.request_id,
"每次构建应该生成不同的 request_id"
);
}
}