Files
hkuds--deeptutor/tests/agents/research/test_dynamic_topic_queue.py
T
wehub-resource-sync e4dcfc49aa
Tests / Import Check (Python 3.13) (push) Has been cancelled
Tests / Import Check (Python 3.14) (push) Has been cancelled
Tests / Python Tests (Python 3.11) (push) Has been cancelled
Tests / Python Tests (Python 3.12) (push) Has been cancelled
Tests / Python Tests (Python 3.14) (push) Has been cancelled
Tests / Test Summary (push) Has been cancelled
Tests / Lint and Format (push) Has been cancelled
Tests / Web Node Tests (push) Has been cancelled
Tests / Import Check (Python 3.11) (push) Has been cancelled
Tests / Import Check (Python 3.12) (push) Has been cancelled
Tests / Python Tests (Python 3.13) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:00:43 +08:00

127 lines
4.1 KiB
Python

"""Unit tests for the queue extensions used by the new research pipeline.
The new agentic-loop refactor relies on three additions to
:class:`DynamicTopicQueue`:
* ``is_full()`` — capacity check without raising
* ``find_similar()`` — fuzzy dedup so the ``APPEND`` label can't
silently flood the queue with near-duplicate sub-topics
* ``append_child()`` — non-raising tail append that records the parent
block id in ``metadata`` for later topic-tree reconstruction
"""
from __future__ import annotations
from deeptutor.agents.research.data_structures import (
DEFAULT_TOPIC_SIMILARITY_THRESHOLD,
DynamicTopicQueue,
TopicStatus,
)
def _queue(max_length: int | None = None) -> DynamicTopicQueue:
return DynamicTopicQueue("test", max_length=max_length)
def test_is_full_returns_false_when_no_cap_configured() -> None:
q = _queue()
for i in range(50):
q.add_block(f"topic {i}", "")
assert q.is_full() is False
def test_is_full_returns_true_at_cap() -> None:
q = _queue(max_length=2)
q.add_block("a", "")
assert q.is_full() is False
q.add_block("b", "")
assert q.is_full() is True
def test_find_similar_exact_match_returns_block() -> None:
q = _queue()
a = q.add_block("Quantum Entanglement Basics", "")
match = q.find_similar("quantum entanglement basics")
assert match is a
def test_find_similar_returns_fuzzy_match_above_threshold() -> None:
q = _queue()
a = q.add_block("Quantum entanglement basics", "")
# Reordered words / slight rewording — should still match above 0.85
match = q.find_similar("Quantum entanglement: basic concepts")
# The default threshold accepts highly similar titles; verify we get
# back the only existing block.
if match is not None:
assert match is a
def test_find_similar_catches_reordered_token_equivalents() -> None:
q = _queue()
a = q.add_block("AI safety governance frameworks", "")
assert q.find_similar("Governance framework for AI safety") is a
def test_find_similar_rejects_distinct_topic() -> None:
q = _queue()
q.add_block("Photosynthesis fundamentals", "")
assert q.find_similar("History of jazz music") is None
def test_find_similar_honours_custom_threshold() -> None:
q = _queue()
q.add_block("Photosynthesis fundamentals", "")
# Force a punishingly high threshold so even close variants miss.
assert q.find_similar("Photosynthesis basics", threshold=0.99) is None
def test_find_similar_returns_none_for_empty_title() -> None:
q = _queue()
q.add_block("x", "")
assert q.find_similar("") is None
assert q.find_similar(" ") is None
def test_append_child_returns_new_block_with_parent_id_in_metadata() -> None:
q = _queue()
parent = q.add_block("Parent topic", "ctx")
child = q.append_child(parent=parent, sub_topic="Child topic", overview="more")
assert child is not None
assert child.sub_topic == "Child topic"
assert child.overview == "more"
assert child.metadata.get("parent_block_id") == parent.block_id
assert child.status == TopicStatus.PENDING
# New blocks land at the tail.
assert q.blocks[-1] is child
def test_append_child_without_parent_records_no_lineage() -> None:
q = _queue()
child = q.append_child(parent=None, sub_topic="orphan", overview="")
assert child is not None
assert "parent_block_id" not in child.metadata
def test_append_child_returns_none_when_queue_full() -> None:
q = _queue(max_length=1)
q.add_block("only one", "")
rejected = q.append_child(parent=None, sub_topic="overflow", overview="")
assert rejected is None
assert len(q.blocks) == 1
def test_append_child_increments_counter_consistently_with_add_block() -> None:
"""``add_block`` and ``append_child`` must share the same id allocator."""
q = _queue()
a = q.add_block("a", "")
b = q.append_child(parent=a, sub_topic="b", overview="")
c = q.add_block("c", "")
assert a.block_id == "block_1"
assert b is not None and b.block_id == "block_2"
assert c.block_id == "block_3"
def test_default_threshold_constant_in_reasonable_range() -> None:
assert 0.7 <= DEFAULT_TOPIC_SIMILARITY_THRESHOLD <= 0.95