Skip to content

Commit f29a51d

Browse files
committed
[TEST] adding tests for ID Generator and associated classes
1 parent 03fa4c2 commit f29a51d

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

tests/server/test_id_generator.py

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import uuid
2+
from unittest.mock import patch
3+
4+
import pytest
5+
6+
from a2a.server.id_generator import IDGeneratorContext, IDGenerator, UUIDGenerator
7+
8+
9+
class TestIDGeneratorContext:
10+
"""Tests for IDGeneratorContext."""
11+
12+
def test_context_creation_with_all_fields(self):
13+
"""Test creating context with all fields populated."""
14+
context = IDGeneratorContext(task_id="task_123", context_id="context_456")
15+
assert context.task_id == "task_123"
16+
assert context.context_id == "context_456"
17+
18+
def test_context_creation_with_defaults(self):
19+
"""Test creating context with default None values."""
20+
context = IDGeneratorContext()
21+
assert context.task_id is None
22+
assert context.context_id is None
23+
24+
def test_context_creation_with_partial_fields(self):
25+
"""Test creating context with only some fields populated."""
26+
context = IDGeneratorContext(task_id="task_123")
27+
assert context.task_id == "task_123"
28+
assert context.context_id is None
29+
30+
def test_context_mutability(self):
31+
"""Test that context fields can be updated (Pydantic models are mutable by default)."""
32+
context = IDGeneratorContext(task_id="task_123")
33+
context.task_id = "task_456"
34+
assert context.task_id == "task_456"
35+
36+
def test_context_validation(self):
37+
"""Test that context validates field types."""
38+
context = IDGeneratorContext(task_id="valid_string")
39+
assert isinstance(context.task_id, str)
40+
41+
42+
class TestIDGenerator:
43+
"""Tests for IDGenerator abstract base class."""
44+
45+
def test_cannot_instantiate_abstract_class(self):
46+
"""Test that IDGenerator cannot be instantiated directly."""
47+
with pytest.raises(TypeError):
48+
IDGenerator() # noqa
49+
50+
def test_subclass_must_implement_generate(self):
51+
"""Test that subclasses must implement the generate method."""
52+
53+
class IncompleteGenerator(IDGenerator): # noqa
54+
pass
55+
56+
with pytest.raises(TypeError):
57+
IncompleteGenerator() # noqa
58+
59+
def test_valid_subclass_implementation(self):
60+
"""Test that a valid subclass can be instantiated."""
61+
62+
class ValidGenerator(IDGenerator):
63+
def generate(self, context: IDGeneratorContext) -> str:
64+
return "test_id"
65+
66+
generator = ValidGenerator()
67+
assert generator.generate(IDGeneratorContext()) == "test_id"
68+
69+
70+
class TestUUIDGenerator:
71+
"""Tests for UUIDGenerator implementation."""
72+
73+
def test_generate_returns_string(self):
74+
"""Test that generate returns a string."""
75+
generator = UUIDGenerator()
76+
context = IDGeneratorContext()
77+
result = generator.generate(context)
78+
assert isinstance(result, str)
79+
80+
def test_generate_returns_valid_uuid(self):
81+
"""Test that generate returns a valid UUID format."""
82+
generator = UUIDGenerator()
83+
context = IDGeneratorContext()
84+
result = generator.generate(context)
85+
86+
# This should not raise an exception if result is a valid UUID
87+
uuid.UUID(result)
88+
89+
def test_generate_returns_uuid_version_4(self):
90+
"""Test that generate returns a UUID version 4."""
91+
generator = UUIDGenerator()
92+
context = IDGeneratorContext()
93+
result = generator.generate(context)
94+
95+
parsed_uuid = uuid.UUID(result)
96+
assert parsed_uuid.version == 4
97+
98+
def test_generate_ignores_context(self):
99+
"""Test that generate ignores the context parameter."""
100+
generator = UUIDGenerator()
101+
context1 = IDGeneratorContext(task_id="task_1", context_id="context_1")
102+
context2 = IDGeneratorContext(task_id="task_2", context_id="context_2")
103+
104+
result1 = generator.generate(context1)
105+
result2 = generator.generate(context2)
106+
107+
# Both should be valid UUIDs but different
108+
uuid.UUID(result1)
109+
uuid.UUID(result2)
110+
assert result1 != result2
111+
112+
def test_generate_produces_unique_ids(self):
113+
"""Test that multiple calls produce unique IDs."""
114+
generator = UUIDGenerator()
115+
context = IDGeneratorContext()
116+
117+
ids = [generator.generate(context) for _ in range(100)]
118+
119+
# All IDs should be unique
120+
assert len(ids) == len(set(ids))
121+
122+
def test_generate_with_empty_context(self):
123+
"""Test that generate works with an empty context."""
124+
generator = UUIDGenerator()
125+
context = IDGeneratorContext()
126+
result = generator.generate(context)
127+
128+
assert isinstance(result, str)
129+
uuid.UUID(result)
130+
131+
def test_generate_with_populated_context(self):
132+
"""Test that generate works with a populated context."""
133+
generator = UUIDGenerator()
134+
context = IDGeneratorContext(task_id="task_123", context_id="context_456")
135+
result = generator.generate(context)
136+
137+
assert isinstance(result, str)
138+
uuid.UUID(result)
139+
140+
@patch('uuid.uuid4')
141+
def test_generate_calls_uuid4(self, mock_uuid4):
142+
"""Test that generate uses uuid.uuid4() internally."""
143+
mock_uuid = uuid.UUID('12345678-1234-5678-1234-567812345678')
144+
mock_uuid4.return_value = mock_uuid
145+
146+
generator = UUIDGenerator()
147+
context = IDGeneratorContext()
148+
result = generator.generate(context)
149+
150+
mock_uuid4.assert_called_once()
151+
assert result == str(mock_uuid)
152+
153+
def test_generator_is_instance_of_id_generator(self):
154+
"""Test that UUIDGenerator is an instance of IDGenerator."""
155+
generator = UUIDGenerator()
156+
assert isinstance(generator, IDGenerator)
157+
158+
def test_multiple_generators_produce_different_ids(self):
159+
"""Test that multiple generator instances produce different IDs."""
160+
generator1 = UUIDGenerator()
161+
generator2 = UUIDGenerator()
162+
context = IDGeneratorContext()
163+
164+
result1 = generator1.generate(context)
165+
result2 = generator2.generate(context)
166+
167+
assert result1 != result2

0 commit comments

Comments
 (0)