Skip to content

Commit 4722f22

Browse files
Koushik-Salammagarinagug
authored andcommitted
test(events): add unit tests for Event helper methods
Add a dedicated test module for the Event class, which previously had only incidental coverage. Covers is_final_response(), get_function_calls(), get_function_responses(), has_trailing_code_execution_result(), and automatic id generation, including edge cases such as events with no content, empty parts lists, and the skip_summarization / long_running_tool_ids early-return overrides. Merge google/adk-python#5948 Change-Id: If05c49f82c7bb73d8c39be548434672497a770c2
1 parent 98f1ee0 commit 4722f22

1 file changed

Lines changed: 190 additions & 0 deletions

File tree

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from __future__ import annotations
16+
17+
"""Unit tests for the helper methods on the Event class."""
18+
19+
from google.adk.events.event import Event
20+
from google.adk.events.event_actions import EventActions
21+
from google.genai import types
22+
23+
24+
def _text_part(text: str = 'hello') -> types.Part:
25+
return types.Part(text=text)
26+
27+
28+
def _function_call_part(name: str = 'my_func') -> types.Part:
29+
return types.Part(function_call=types.FunctionCall(name=name, args={'x': 1}))
30+
31+
32+
def _function_response_part(name: str = 'my_func') -> types.Part:
33+
return types.Part(
34+
function_response=types.FunctionResponse(name=name, response={'y': 2})
35+
)
36+
37+
38+
def _code_execution_result_part(output: str = '42') -> types.Part:
39+
return types.Part(
40+
code_execution_result=types.CodeExecutionResult(
41+
outcome=types.Outcome.OUTCOME_OK, output=output
42+
)
43+
)
44+
45+
46+
def _event(parts: list[types.Part] | None = None, **kwargs) -> Event:
47+
content = (
48+
types.Content(role='model', parts=parts) if parts is not None else None
49+
)
50+
return Event(author='agent', content=content, **kwargs)
51+
52+
53+
# --- is_final_response -------------------------------------------------------
54+
55+
56+
def test_is_final_response_plain_text_event_is_final():
57+
event = _event(parts=[_text_part()])
58+
assert event.is_final_response() is True
59+
60+
61+
def test_is_final_response_empty_event_is_final():
62+
event = _event()
63+
assert event.is_final_response() is True
64+
65+
66+
def test_is_final_response_with_function_call_is_not_final():
67+
event = _event(parts=[_text_part(), _function_call_part()])
68+
assert event.is_final_response() is False
69+
70+
71+
def test_is_final_response_with_function_response_is_not_final():
72+
event = _event(parts=[_function_response_part()])
73+
assert event.is_final_response() is False
74+
75+
76+
def test_is_final_response_partial_event_is_not_final():
77+
event = _event(parts=[_text_part()], partial=True)
78+
assert event.is_final_response() is False
79+
80+
81+
def test_is_final_response_with_trailing_code_result_is_not_final():
82+
event = _event(parts=[_text_part(), _code_execution_result_part()])
83+
assert event.is_final_response() is False
84+
85+
86+
def test_is_final_response_skip_summarization_overrides_function_response():
87+
event = _event(
88+
parts=[_function_response_part()],
89+
actions=EventActions(skip_summarization=True),
90+
)
91+
assert event.is_final_response() is True
92+
93+
94+
def test_is_final_response_long_running_tool_ids_overrides_function_call():
95+
event = _event(
96+
parts=[_function_call_part()], long_running_tool_ids={'tool-1'}
97+
)
98+
assert event.is_final_response() is True
99+
100+
101+
# --- get_function_calls ------------------------------------------------------
102+
103+
104+
def test_get_function_calls_returns_calls_in_order():
105+
event = _event(
106+
parts=[
107+
_text_part(),
108+
_function_call_part('first'),
109+
_function_response_part(),
110+
_function_call_part('second'),
111+
]
112+
)
113+
assert [call.name for call in event.get_function_calls()] == [
114+
'first',
115+
'second',
116+
]
117+
118+
119+
def test_get_function_calls_no_content_returns_empty():
120+
assert _event().get_function_calls() == []
121+
122+
123+
def test_get_function_calls_empty_parts_returns_empty():
124+
assert _event(parts=[]).get_function_calls() == []
125+
126+
127+
def test_get_function_calls_text_only_returns_empty():
128+
assert _event(parts=[_text_part()]).get_function_calls() == []
129+
130+
131+
# --- get_function_responses --------------------------------------------------
132+
133+
134+
def test_get_function_responses_returns_responses_in_order():
135+
event = _event(
136+
parts=[
137+
_function_response_part('first'),
138+
_text_part(),
139+
_function_call_part(),
140+
_function_response_part('second'),
141+
]
142+
)
143+
assert [resp.name for resp in event.get_function_responses()] == [
144+
'first',
145+
'second',
146+
]
147+
148+
149+
def test_get_function_responses_no_content_returns_empty():
150+
assert _event().get_function_responses() == []
151+
152+
153+
def test_get_function_responses_empty_parts_returns_empty():
154+
assert _event(parts=[]).get_function_responses() == []
155+
156+
157+
# --- has_trailing_code_execution_result --------------------------------------
158+
159+
160+
def test_has_trailing_code_execution_result_true_when_last():
161+
event = _event(parts=[_text_part(), _code_execution_result_part()])
162+
assert event.has_trailing_code_execution_result() is True
163+
164+
165+
def test_has_trailing_code_execution_result_false_when_not_last():
166+
event = _event(parts=[_code_execution_result_part(), _text_part()])
167+
assert event.has_trailing_code_execution_result() is False
168+
169+
170+
def test_has_trailing_code_execution_result_false_no_content():
171+
assert _event().has_trailing_code_execution_result() is False
172+
173+
174+
def test_has_trailing_code_execution_result_false_empty_parts():
175+
assert _event(parts=[]).has_trailing_code_execution_result() is False
176+
177+
178+
# --- id generation (model_post_init) -----------------------------------------
179+
180+
181+
def test_event_id_auto_assigned_when_missing():
182+
assert _event().id != ''
183+
184+
185+
def test_event_ids_are_unique():
186+
assert _event().id != _event().id
187+
188+
189+
def test_event_id_preserved_when_provided():
190+
assert _event(id='fixed-id').id == 'fixed-id'

0 commit comments

Comments
 (0)