Skip to content

Commit beeddbd

Browse files
committed
Add unit tests for ArtifactStreamer helper
1 parent 4b8c0c0 commit beeddbd

1 file changed

Lines changed: 102 additions & 0 deletions

File tree

tests/utils/test_artifact.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
Artifact,
88
DataPart,
99
Part,
10+
TaskArtifactUpdateEvent,
1011
TextPart,
1112
)
1213
from a2a.utils.artifact import (
14+
ArtifactStreamer,
1315
get_artifact_text,
1416
new_artifact,
1517
new_data_artifact,
@@ -155,5 +157,105 @@ def test_get_artifact_text_empty_parts(self):
155157
assert result == ''
156158

157159

160+
class TestArtifactStreamer(unittest.TestCase):
161+
def setUp(self):
162+
self.context_id = 'ctx-123'
163+
self.task_id = 'task-456'
164+
165+
def test_generates_stable_artifact_id(self):
166+
streamer = ArtifactStreamer(self.context_id, self.task_id)
167+
e1 = streamer.append('hello ')
168+
e2 = streamer.append('world')
169+
self.assertEqual(e1.artifact.artifact_id, e2.artifact.artifact_id)
170+
171+
def test_uses_explicit_artifact_id(self):
172+
streamer = ArtifactStreamer(
173+
self.context_id, self.task_id, artifact_id='my-fixed-id'
174+
)
175+
event = streamer.append('chunk')
176+
self.assertEqual(event.artifact.artifact_id, 'my-fixed-id')
177+
178+
@patch('a2a.utils.artifact.uuid.uuid4')
179+
def test_generated_id_comes_from_uuid4(self, mock_uuid4):
180+
mock_uuid = uuid.UUID('abcdef12-1234-5678-1234-567812345678')
181+
mock_uuid4.return_value = mock_uuid
182+
streamer = ArtifactStreamer(self.context_id, self.task_id)
183+
self.assertEqual(streamer.artifact_id, str(mock_uuid))
184+
185+
def test_default_name_is_response(self):
186+
streamer = ArtifactStreamer(self.context_id, self.task_id)
187+
event = streamer.append('text')
188+
self.assertEqual(event.artifact.name, 'response')
189+
190+
def test_custom_name(self):
191+
streamer = ArtifactStreamer(
192+
self.context_id, self.task_id, name='summary'
193+
)
194+
event = streamer.append('text')
195+
self.assertEqual(event.artifact.name, 'summary')
196+
197+
def test_append_returns_task_artifact_update_event(self):
198+
streamer = ArtifactStreamer(self.context_id, self.task_id)
199+
event = streamer.append('chunk')
200+
self.assertIsInstance(event, TaskArtifactUpdateEvent)
201+
202+
def test_append_sets_correct_context_and_task(self):
203+
streamer = ArtifactStreamer(self.context_id, self.task_id)
204+
event = streamer.append('chunk')
205+
self.assertEqual(event.context_id, self.context_id)
206+
self.assertEqual(event.task_id, self.task_id)
207+
208+
def test_append_sets_append_true_last_chunk_false(self):
209+
streamer = ArtifactStreamer(self.context_id, self.task_id)
210+
event = streamer.append('chunk')
211+
self.assertTrue(event.append)
212+
self.assertFalse(event.last_chunk)
213+
214+
def test_append_creates_single_text_part(self):
215+
streamer = ArtifactStreamer(self.context_id, self.task_id)
216+
event = streamer.append('hello')
217+
self.assertEqual(len(event.artifact.parts), 1)
218+
self.assertIsInstance(event.artifact.parts[0].root, TextPart)
219+
self.assertEqual(event.artifact.parts[0].root.text, 'hello')
220+
221+
def test_finalize_returns_task_artifact_update_event(self):
222+
streamer = ArtifactStreamer(self.context_id, self.task_id)
223+
event = streamer.finalize()
224+
self.assertIsInstance(event, TaskArtifactUpdateEvent)
225+
226+
def test_finalize_sets_append_true_last_chunk_true(self):
227+
streamer = ArtifactStreamer(self.context_id, self.task_id)
228+
event = streamer.finalize()
229+
self.assertTrue(event.append)
230+
self.assertTrue(event.last_chunk)
231+
232+
def test_finalize_has_empty_parts(self):
233+
streamer = ArtifactStreamer(self.context_id, self.task_id)
234+
event = streamer.finalize()
235+
self.assertEqual(event.artifact.parts, [])
236+
237+
def test_finalize_uses_same_artifact_id_as_append(self):
238+
streamer = ArtifactStreamer(self.context_id, self.task_id)
239+
append_event = streamer.append('text')
240+
finalize_event = streamer.finalize()
241+
self.assertEqual(
242+
append_event.artifact.artifact_id,
243+
finalize_event.artifact.artifact_id,
244+
)
245+
246+
def test_multiple_appends_all_share_artifact_id(self):
247+
streamer = ArtifactStreamer(self.context_id, self.task_id)
248+
events = [streamer.append(f'chunk-{i}') for i in range(5)]
249+
ids = {e.artifact.artifact_id for e in events}
250+
self.assertEqual(len(ids), 1)
251+
252+
def test_multiple_appends_carry_distinct_text(self):
253+
streamer = ArtifactStreamer(self.context_id, self.task_id)
254+
texts = ['Hello, ', 'world', '!']
255+
events = [streamer.append(t) for t in texts]
256+
result_texts = [e.artifact.parts[0].root.text for e in events]
257+
self.assertEqual(result_texts, texts)
258+
259+
158260
if __name__ == '__main__':
159261
unittest.main()

0 commit comments

Comments
 (0)