use super::*;
use crate::completion::CompletionRequest;
use crate::driver::Model;
use crate::providers::anthropic::{completion::CLAUDE_SONNET_4_6, wire::AnthropicConfig};
use crate::test_utils::{MockHttpResponse, SequencedHttpClient};
fn messages_body() -> String {
serde_json::json!({
"type": "message",
"id": "msg_1",
"role": "assistant",
"model": CLAUDE_SONNET_4_6,
"content": [
{"type": "text", "text": "Looking."},
{"type": "tool_use", "id": "toolu_1", "name": "read", "input": {"path": "a.rs"}}
],
"stop_reason": "tool_use",
"usage": {"input_tokens": 12, "output_tokens": 7}
})
.to_string()
}
#[tokio::test]
async fn a_whole_body_decodes_as_a_unary_call_gives_it() {
let wire = AnthropicConfig::new("test-key").completion(CLAUDE_SONNET_4_6);
let request = CompletionRequest::new("read a.rs");
let http = SequencedHttpClient::new([MockHttpResponse::success(messages_body())]);
let called = Model::new(wire.clone(), http)
.call(request.clone())
.await
.expect("the call succeeds");
let decoded = decode_reply(
&wire,
&request,
Mode::Unary,
[WireFrame::Bytes(messages_body().into_bytes())],
)
.expect("the body decodes");
assert_eq!(decoded, called);
}
#[test]
fn frames_that_stop_early_are_truncated() {
let wire = AnthropicConfig::new("test-key").completion(CLAUDE_SONNET_4_6);
let start = serde_json::json!({
"type": "message_start",
"message": {"id": "msg_1", "type": "message", "role": "assistant", "content": [],
"model": CLAUDE_SONNET_4_6, "usage": {"input_tokens": 1, "output_tokens": 0}}
});
let decoded = decode_reply(
&wire,
&CompletionRequest::new("hi"),
Mode::Streaming,
[WireFrame::Text(start.to_string())],
);
assert!(
matches!(decoded, Err(ProviderError::Truncated)),
"{decoded:?}"
);
}
#[test]
fn what_a_model_kept_never_makes_two_models_differ() {
let kept = Prepared::default();
let clone = kept.clone();
assert!(Arc::ptr_eq(&kept.0, &clone.0), "a model's clones share it");
assert_eq!(kept, Prepared::default());
}