|
2 | 2 |
|
3 | 3 | import builtins |
4 | 4 | import sys |
| 5 | +import threading |
5 | 6 | from pathlib import Path |
6 | 7 | from typing import Any |
7 | 8 | from unittest.mock import AsyncMock, MagicMock, patch |
@@ -1051,6 +1052,30 @@ def test_create_agent_from_yaml_path_with_path_object(self, tmp_path): |
1051 | 1052 |
|
1052 | 1053 | assert agent.name == "PathAgent" |
1053 | 1054 |
|
| 1055 | + def test_create_agent_from_yaml_path_reads_utf8(self, tmp_path): |
| 1056 | + """Test create_agent_from_yaml_path reads YAML as UTF-8.""" |
| 1057 | + from unittest.mock import MagicMock |
| 1058 | + |
| 1059 | + from agent_framework_declarative import AgentFactory |
| 1060 | + |
| 1061 | + yaml_file = tmp_path / "unicode_agent.yaml" |
| 1062 | + yaml_file.write_text( |
| 1063 | + """ |
| 1064 | +kind: Prompt |
| 1065 | +name: UnicodeAgent |
| 1066 | +instructions: 政务助手 🏛️ |
| 1067 | +""", |
| 1068 | + encoding="utf-8", |
| 1069 | + ) |
| 1070 | + |
| 1071 | + mock_client = MagicMock() |
| 1072 | + factory = AgentFactory(client=mock_client) |
| 1073 | + with patch("builtins.open", wraps=builtins.open) as mock_open: |
| 1074 | + agent = factory.create_agent_from_yaml_path(yaml_file) |
| 1075 | + |
| 1076 | + mock_open.assert_called_once_with(yaml_file, encoding="utf-8") |
| 1077 | + assert agent.name == "UnicodeAgent" |
| 1078 | + |
1054 | 1079 |
|
1055 | 1080 | class TestAgentFactoryAsyncMethods: |
1056 | 1081 | """Tests for AgentFactory async methods.""" |
@@ -1138,6 +1163,41 @@ async def test_create_agent_from_yaml_path_async_with_string_path(self, tmp_path |
1138 | 1163 |
|
1139 | 1164 | assert agent.name == "AsyncPathAgent" |
1140 | 1165 |
|
| 1166 | + async def test_create_agent_from_yaml_path_async_reads_utf8_off_event_loop(self, tmp_path): |
| 1167 | + """Test async path loading reads UTF-8 without blocking the event-loop thread.""" |
| 1168 | + from unittest.mock import MagicMock |
| 1169 | + |
| 1170 | + from agent_framework_declarative import AgentFactory |
| 1171 | + |
| 1172 | + yaml_file = tmp_path / "async_unicode_agent.yaml" |
| 1173 | + yaml_file.write_text( |
| 1174 | + """ |
| 1175 | +kind: Prompt |
| 1176 | +name: AsyncUnicodeAgent |
| 1177 | +instructions: 政务助手 🏛️ |
| 1178 | +""", |
| 1179 | + encoding="utf-8", |
| 1180 | + ) |
| 1181 | + |
| 1182 | + event_loop_thread_id = threading.get_ident() |
| 1183 | + read_thread_id: int | None = None |
| 1184 | + original_read_text = Path.read_text |
| 1185 | + |
| 1186 | + def tracked_read_text(path: Path, *args, **kwargs): |
| 1187 | + nonlocal read_thread_id |
| 1188 | + read_thread_id = threading.get_ident() |
| 1189 | + assert kwargs["encoding"] == "utf-8" |
| 1190 | + return original_read_text(path, *args, **kwargs) |
| 1191 | + |
| 1192 | + mock_client = MagicMock() |
| 1193 | + factory = AgentFactory(client=mock_client) |
| 1194 | + with patch.object(Path, "read_text", autospec=True, side_effect=tracked_read_text): |
| 1195 | + agent = await factory.create_agent_from_yaml_path_async(yaml_file) |
| 1196 | + |
| 1197 | + assert read_thread_id is not None |
| 1198 | + assert read_thread_id != event_loop_thread_id |
| 1199 | + assert agent.name == "AsyncUnicodeAgent" |
| 1200 | + |
1141 | 1201 |
|
1142 | 1202 | class TestAgentFactoryProviderLookup: |
1143 | 1203 | """Tests for provider configuration lookup.""" |
|
0 commit comments