mod common;
use common::FakeModel;
use lc_core::language_models::BaseChatModel;
use lc_core::tools::ToolDefinition;
use lc_schema::Message;
use lc_testkit::{RecordingProvider, ReplayProvider};
#[tokio::test]
async fn record_then_replay_roundtrip() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("capture.jsonl");
let recorded =
RecordingProvider::new(FakeModel::new("Rust 是一门系统编程语言。"), &path).unwrap();
let result = recorded
.chat(
vec![Message::system("测试"), Message::human("什么是 Rust?")],
None,
)
.await
.unwrap();
assert_eq!(result.content, "Rust 是一门系统编程语言。");
let raw = std::fs::read_to_string(&path).unwrap();
assert_eq!(raw.lines().count(), 1);
let replay = ReplayProvider::from_file(&path).unwrap();
assert_eq!(replay.len(), 1);
let replayed = replay
.chat(vec![Message::human("什么是 Rust?")], None)
.await
.unwrap();
assert_eq!(replayed.content, result.content);
assert_eq!(replayed.model, result.model);
let tokens = replayed.token_usage.as_ref().expect("回放应带 token 计数");
assert_eq!(tokens.prompt_tokens, 2);
assert_eq!(tokens.completion_tokens, 1);
assert_eq!(tokens.total_tokens, 3);
}
#[tokio::test]
async fn record_with_bound_tools_then_replay() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("tools.jsonl");
let recorded = RecordingProvider::new(FakeModel::new("计算结果是 5。"), &path).unwrap();
let bound = recorded.bind_tools(vec![ToolDefinition::new("calculator", "数学计算")]);
let result = bound
.chat(vec![Message::system("测试"), Message::human("2+3=?")], None)
.await
.unwrap();
assert_eq!(result.content, "计算结果是 5。");
let raw = std::fs::read_to_string(&path).unwrap();
assert!(
raw.contains("calculator"),
"录播文件应包含绑定的工具名: {raw}"
);
let replay = ReplayProvider::from_file(&path).unwrap();
assert_eq!(replay.len(), 1);
let replayed = replay
.chat(vec![Message::human("2+3=?")], None)
.await
.unwrap();
assert_eq!(replayed.content, result.content);
}
#[test]
fn old_fixture_without_tools_still_deserializes() {
let line = r#"{"messages":[{"content":"q","type":"human"}],"response":{"content":"a","model":"m","token_usage":{"prompt_tokens":1,"completion_tokens":1,"total_tokens":2}}}"#;
let exchange: lc_testkit::RecordedExchange = serde_json::from_str(line).unwrap();
assert!(exchange.tools.is_none());
}