claude-code-sdk-python/tests/test_message_parser.py
Dickson Tsai 5325dea9fd
Lint
2025-07-19 20:19:40 -07:00

121 lines
4.8 KiB
Python

"""Tests for message parser error handling."""
import pytest
from claude_code_sdk._errors import MessageParseError
from claude_code_sdk._internal.message_parser import parse_message
from claude_code_sdk.types import (
AssistantMessage,
ResultMessage,
SystemMessage,
TextBlock,
ToolUseBlock,
UserMessage,
)
class TestMessageParser:
"""Test message parsing with the new exception behavior."""
def test_parse_valid_user_message(self):
"""Test parsing a valid user message."""
data = {
"type": "user",
"message": {"content": [{"type": "text", "text": "Hello"}]},
}
message = parse_message(data)
assert isinstance(message, UserMessage)
def test_parse_valid_assistant_message(self):
"""Test parsing a valid assistant message."""
data = {
"type": "assistant",
"message": {
"content": [
{"type": "text", "text": "Hello"},
{
"type": "tool_use",
"id": "tool_123",
"name": "Read",
"input": {"file_path": "/test.txt"},
},
]
},
}
message = parse_message(data)
assert isinstance(message, AssistantMessage)
assert len(message.content) == 2
assert isinstance(message.content[0], TextBlock)
assert isinstance(message.content[1], ToolUseBlock)
def test_parse_valid_system_message(self):
"""Test parsing a valid system message."""
data = {"type": "system", "subtype": "start"}
message = parse_message(data)
assert isinstance(message, SystemMessage)
assert message.subtype == "start"
def test_parse_valid_result_message(self):
"""Test parsing a valid result message."""
data = {
"type": "result",
"subtype": "success",
"duration_ms": 1000,
"duration_api_ms": 500,
"is_error": False,
"num_turns": 2,
"session_id": "session_123",
}
message = parse_message(data)
assert isinstance(message, ResultMessage)
assert message.subtype == "success"
def test_parse_invalid_data_type(self):
"""Test that non-dict data raises MessageParseError."""
with pytest.raises(MessageParseError) as exc_info:
parse_message("not a dict") # type: ignore
assert "Invalid message data type" in str(exc_info.value)
assert "expected dict, got str" in str(exc_info.value)
def test_parse_missing_type_field(self):
"""Test that missing 'type' field raises MessageParseError."""
with pytest.raises(MessageParseError) as exc_info:
parse_message({"message": {"content": []}})
assert "Message missing 'type' field" in str(exc_info.value)
def test_parse_unknown_message_type(self):
"""Test that unknown message type raises MessageParseError."""
with pytest.raises(MessageParseError) as exc_info:
parse_message({"type": "unknown_type"})
assert "Unknown message type: unknown_type" in str(exc_info.value)
def test_parse_user_message_missing_fields(self):
"""Test that user message with missing fields raises MessageParseError."""
with pytest.raises(MessageParseError) as exc_info:
parse_message({"type": "user"})
assert "Missing required field in user message" in str(exc_info.value)
def test_parse_assistant_message_missing_fields(self):
"""Test that assistant message with missing fields raises MessageParseError."""
with pytest.raises(MessageParseError) as exc_info:
parse_message({"type": "assistant"})
assert "Missing required field in assistant message" in str(exc_info.value)
def test_parse_system_message_missing_fields(self):
"""Test that system message with missing fields raises MessageParseError."""
with pytest.raises(MessageParseError) as exc_info:
parse_message({"type": "system"})
assert "Missing required field in system message" in str(exc_info.value)
def test_parse_result_message_missing_fields(self):
"""Test that result message with missing fields raises MessageParseError."""
with pytest.raises(MessageParseError) as exc_info:
parse_message({"type": "result", "subtype": "success"})
assert "Missing required field in result message" in str(exc_info.value)
def test_message_parse_error_contains_data(self):
"""Test that MessageParseError contains the original data."""
data = {"type": "unknown", "some": "data"}
with pytest.raises(MessageParseError) as exc_info:
parse_message(data)
assert exc_info.value.data == data