Skip to content

Commit db9a56a

Browse files
committed
test: improve coverage for Mistral reasoning support
Add tests for unexpected content types, empty messages, JSON string input to response converter, async empty messages, and async streaming with reasoning warning.
1 parent 9f1d3b1 commit db9a56a

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

integrations/mistral/tests/test_mistral_chat_generator.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,3 +1167,44 @@ def test_prepare_api_call_preserves_reasoning(self, monkeypatch):
11671167
assert assistant_msg["content"][0]["thinking"][0]["text"] == "2+2 equals 4"
11681168
assert assistant_msg["content"][1]["type"] == "text"
11691169
assert assistant_msg["content"][1]["text"] == "The answer is 4."
1170+
1171+
def test_parse_mistral_content_unexpected_type(self):
1172+
text, reasoning = _parse_mistral_content(42)
1173+
assert text == "42"
1174+
assert reasoning is None
1175+
1176+
def test_parse_mistral_content_unexpected_object(self):
1177+
text, reasoning = _parse_mistral_content(3.14)
1178+
assert text == "3.14"
1179+
assert reasoning is None
1180+
1181+
def test_run_empty_messages(self, monkeypatch):
1182+
monkeypatch.setenv("MISTRAL_API_KEY", "fake-api-key")
1183+
component = MistralChatGenerator()
1184+
response = component.run([])
1185+
assert response == {"replies": []}
1186+
1187+
def test_convert_response_from_json_string(self):
1188+
json_str = json.dumps({
1189+
"id": "test",
1190+
"model": "mistral-small-latest",
1191+
"choices": [
1192+
{
1193+
"finish_reason": "stop",
1194+
"index": 0,
1195+
"message": {
1196+
"role": "assistant",
1197+
"content": [
1198+
{"type": "thinking", "thinking": [{"type": "text", "text": "Thinking."}]},
1199+
{"type": "text", "text": "Answer."},
1200+
],
1201+
},
1202+
}
1203+
],
1204+
"usage": {"prompt_tokens": 5, "completion_tokens": 10, "total_tokens": 15},
1205+
})
1206+
messages = _convert_mistral_response_to_chat_messages(json_str)
1207+
assert len(messages) == 1
1208+
assert messages[0].text == "Answer."
1209+
assert messages[0].reasoning is not None
1210+
assert messages[0].reasoning.reasoning_text == "Thinking."

integrations/mistral/tests/test_mistral_chat_generator_async.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,3 +308,30 @@ async def test_run_async_with_reasoning(self, chat_messages, monkeypatch):
308308
assert msg.text == "Async answer."
309309
assert msg.reasoning is not None
310310
assert msg.reasoning.reasoning_text == "Async reasoning content."
311+
312+
@pytest.mark.asyncio
313+
async def test_run_async_empty_messages(self, monkeypatch):
314+
monkeypatch.setenv("MISTRAL_API_KEY", "fake-api-key")
315+
component = MistralChatGenerator()
316+
response = await component.run_async([])
317+
assert response == {"replies": []}
318+
319+
@pytest.mark.asyncio
320+
async def test_run_async_streaming_with_reasoning_logs_warning(self, monkeypatch, caplog):
321+
import logging
322+
323+
from haystack.components.generators.utils import print_streaming_chunk
324+
from haystack.dataclasses import ChatMessage
325+
326+
monkeypatch.setenv("MISTRAL_API_KEY", "fake-api-key")
327+
component = MistralChatGenerator(
328+
generation_kwargs={"reasoning_effort": "high"},
329+
streaming_callback=print_streaming_chunk,
330+
)
331+
332+
with (
333+
caplog.at_level(logging.WARNING),
334+
patch.object(component, "_prepare_api_call", side_effect=RuntimeError),
335+
pytest.raises(RuntimeError),
336+
):
337+
await component.run_async([ChatMessage.from_user("test")])

0 commit comments

Comments
 (0)