refactor: enhance summarization widget with streaming support and text accumulation
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"""Tests for the summarization event pipeline and display widgets."""
|
||||
|
||||
from EvoScientist.stream.emitter import StreamEventEmitter
|
||||
from EvoScientist.stream.events import _extract_summarization_text
|
||||
from EvoScientist.stream.state import StreamState
|
||||
|
||||
|
||||
@@ -44,12 +45,12 @@ class TestSummarizationState:
|
||||
assert etype == "summarization"
|
||||
assert state.summarization_text == "summary"
|
||||
|
||||
def test_overwrites_previous(self):
|
||||
"""Each summarization replaces (not appends) the previous text."""
|
||||
def test_accumulates_chunks(self):
|
||||
"""Summarization chunks are accumulated (streaming)."""
|
||||
state = StreamState()
|
||||
state.handle_event({"type": "summarization", "content": "first"})
|
||||
state.handle_event({"type": "summarization", "content": "second"})
|
||||
assert state.summarization_text == "second"
|
||||
assert state.summarization_text == "firstsecond"
|
||||
|
||||
def test_get_display_args_includes_field(self):
|
||||
state = StreamState()
|
||||
@@ -158,6 +159,24 @@ class TestSummarizationWidget:
|
||||
w._content = "x" * 2500
|
||||
assert w._char_count_label() == "2.5k chars"
|
||||
|
||||
def test_append_text(self):
|
||||
from EvoScientist.cli.widgets.summarization_widget import SummarizationWidget
|
||||
|
||||
w = SummarizationWidget()
|
||||
w.append_text("hello ")
|
||||
w.append_text("world")
|
||||
assert w._content == "hello world"
|
||||
assert w._is_active is True
|
||||
|
||||
def test_finalize(self):
|
||||
from EvoScientist.cli.widgets.summarization_widget import SummarizationWidget
|
||||
|
||||
w = SummarizationWidget()
|
||||
w.append_text("some summary")
|
||||
w.finalize()
|
||||
assert w._is_active is False
|
||||
assert w._collapsed is True
|
||||
|
||||
def test_toggle_collapsed(self):
|
||||
from EvoScientist.cli.widgets.summarization_widget import SummarizationWidget
|
||||
|
||||
@@ -167,3 +186,48 @@ class TestSummarizationWidget:
|
||||
assert w._collapsed is False
|
||||
w._collapsed = not w._collapsed
|
||||
assert w._collapsed is True
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _extract_summarization_text helper
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestExtractSummarizationText:
|
||||
"""Content extraction from summarization chunks."""
|
||||
|
||||
def test_string_content(self):
|
||||
class Msg:
|
||||
content = "hello world"
|
||||
assert _extract_summarization_text(Msg()) == "hello world"
|
||||
|
||||
def test_content_blocks(self):
|
||||
class Msg:
|
||||
content = [{"type": "text", "text": "part1"}, {"type": "text", "text": "part2"}]
|
||||
assert _extract_summarization_text(Msg()) == "part1part2"
|
||||
|
||||
def test_content_blocks_with_index(self):
|
||||
"""Content blocks may include 'index' field — should still extract text."""
|
||||
class Msg:
|
||||
content = [{"type": "text", "text": " vs", "index": 1}]
|
||||
assert _extract_summarization_text(Msg()) == " vs"
|
||||
|
||||
def test_empty_list(self):
|
||||
class Msg:
|
||||
content = []
|
||||
assert _extract_summarization_text(Msg()) == ""
|
||||
|
||||
def test_no_content_attr(self):
|
||||
class Msg:
|
||||
pass
|
||||
assert _extract_summarization_text(Msg()) == ""
|
||||
|
||||
def test_mixed_block_types(self):
|
||||
class Msg:
|
||||
content = [{"type": "text", "text": "hello"}, {"type": "image", "url": "..."}]
|
||||
assert _extract_summarization_text(Msg()) == "hello"
|
||||
|
||||
def test_string_blocks_in_list(self):
|
||||
class Msg:
|
||||
content = ["hello", "world"]
|
||||
assert _extract_summarization_text(Msg()) == "helloworld"
|
||||
|
||||
Reference in New Issue
Block a user