//! json 模块(领域类型与 `JsonValue` 之间的转换)的集成测试。 //! Integration tests for the json module (conversions between domain types and `JsonValue`). use focus_core::json::{messages_from_json, messages_to_json, FromJson, ToJson}; use focus_core::model::*; use focus_json::JsonValue; #[test] fn text_block_roundtrip() { let b = ContentBlock::text("hello"); let j = b.to_json(); let back = ContentBlock::from_json(&j).unwrap(); assert_eq!(b, back); } #[test] fn tool_call_roundtrip() { let mut args = JsonValue::obj(); args.insert("path", "/tmp/x".into()).ok(); let tc = ToolCall { id: "call_1".into(), name: "read".into(), arguments: args, }; let j = tc.to_json(); let back = ToolCall::from_json(&j).unwrap(); assert_eq!(tc, back); } #[test] fn user_message_roundtrip() { let m = Message::user_text("hello world"); let j = m.to_json(); let back = Message::from_json(&j).unwrap(); assert_eq!(m, back); } #[test] fn assistant_message_with_tool_call_roundtrip() { let mut args = JsonValue::obj(); args.insert("cmd", "ls".into()).ok(); let m = Message::Assistant(AssistantMessage { content: vec![ ContentBlock::text("running ls"), ContentBlock::ToolCall(ToolCall { id: "c1".into(), name: "bash".into(), arguments: args, }), ], model: "claude-test".into(), usage: Usage { input_tokens: 10, output_tokens: 5, ..Default::default() }, stop_reason: StopReason::ToolUse, error_message: None, timestamp: 12345, }); let j = m.to_json(); let back = Message::from_json(&j).unwrap(); assert_eq!(m, back); } #[test] fn tool_result_roundtrip() { let mut details = JsonValue::obj(); details.insert("exitCode", (0.0).into()).ok(); let m = Message::ToolResult(ToolResultMessage { tool_call_id: "c1".into(), tool_name: "bash".into(), content: vec![ContentBlock::text("file1\nfile2")], details, is_error: false, timestamp: 99, }); let j = m.to_json(); let back = Message::from_json(&j).unwrap(); assert_eq!(m, back); } #[test] fn messages_array_roundtrip() { let msgs = vec![ Message::user_text("hi"), Message::Assistant(AssistantMessage { content: vec![ContentBlock::text("hello")], model: "m".into(), usage: Usage::default(), stop_reason: StopReason::Stop, error_message: None, timestamp: 1, }), ]; let j = messages_to_json(&msgs); let back = messages_from_json(&j).unwrap(); assert_eq!(msgs, back); } #[test] fn rejects_missing_role() { let bad = JsonValue::obj(); assert!(Message::from_json(&bad).is_err()); }