11"""Deterministic Mock Tests for ModelOutputThunk.astream() incremental return behavior.
22
3- Tests that astream() returns only new content added since the beginning of
4- each astream() call, not the entire accumulated value. Uses manual queue
5- injection to bypass LLM calls and network operations, guaranteeing determinism.
3+ Tests that astream() returns only the incremental content added during each call.
4+ All astream() chunks concatenated should equal the full final value. Calling
5+ astream() on a computed MOT raises RuntimeError. Uses manual queue injection to
6+ bypass LLM calls and network operations, guaranteeing determinism.
67"""
78
89import asyncio
@@ -87,12 +88,13 @@ async def test_astream_multiple_calls_accumulate_correctly():
8788 mot ._async_queue .put_nowait (None )
8889
8990 chunk2 = await mot .astream ()
90- assert chunk2 == "chunk"
91-
92- final_val = await mot .avalue ()
91+ # astream() returns only the incremental content added during this call
92+ assert chunk2 == "nk"
9393
9494 assert mot .is_computed ()
95- assert final_val == "chunk"
95+ # All astream() chunks concatenated should equal the full value
96+ assert chunk1 + chunk2 == "chunk"
97+ assert mot .value == "chunk"
9698
9799
98100@pytest .mark .asyncio
@@ -126,14 +128,14 @@ async def test_astream_empty_beginning():
126128
127129
128130@pytest .mark .asyncio
129- async def test_astream_computed_returns_full_value ():
130- """Test that astream returns full value when already computed."""
131- # Precomputed thunk skips queue checking completely
131+ async def test_astream_computed_raises_error ():
132+ """Test that astream raises RuntimeError when already computed."""
133+ # Precomputed thunk is already computed
132134 mot = ModelOutputThunk (value = "Hello, world!" )
133135
134- # For a precomputed thunk, astream directly returns value
135- result = await mot . astream ()
136- assert result == "Hello, world!"
136+ # astream() on a computed MOT now raises RuntimeError
137+ with pytest . raises ( RuntimeError , match = "Streaming has finished" ):
138+ await mot . astream ()
137139
138140
139141@pytest .mark .asyncio
@@ -155,8 +157,9 @@ async def test_astream_final_call_returns_full_value():
155157 # Calling astream here processes "part3" and `None`, flagging it as done
156158 chunk3 = await mot .astream ()
157159
158- final_val = await mot .avalue ()
160+ # The final astream() call returns only the incremental content, not the full value
161+ assert chunk3 == "part3"
159162
160- # The final chunk logically completes the thunk, returning the full value instead of a slice.
161- assert chunk3 == "part1part2part3"
162- assert chunk3 == final_val
163+ # All chunks concatenated equal the full value
164+ assert chunk1 + chunk2 + chunk3 == "part1part2part3"
165+ assert mot . value == "part1part2part3"
0 commit comments