Skip to content

Commit cd80e62

Browse files
Copilothzhangxyz
andcommitted
Add comprehensive tests for egg.py based on output.py tests
Co-authored-by: hzhangxyz <11623447+hzhangxyz@users.noreply.github.com>
1 parent e12768a commit cd80e62

1 file changed

Lines changed: 203 additions & 0 deletions

File tree

tests/test_egg.py

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
import asyncio
2+
import tempfile
3+
import pathlib
4+
import pytest
5+
import pytest_asyncio
6+
from sqlalchemy import select
7+
from ddss.orm import initialize_database, Facts, Ideas
8+
from ddss.egg import main
9+
10+
11+
@pytest_asyncio.fixture
12+
async def temp_db():
13+
"""Fixture to create a temporary database."""
14+
with tempfile.TemporaryDirectory() as tmpdir:
15+
db_path = pathlib.Path(tmpdir) / "test.db"
16+
addr = f"sqlite+aiosqlite:///{db_path.as_posix()}"
17+
engine, session = await initialize_database(addr)
18+
yield addr, engine, session
19+
await engine.dispose()
20+
21+
22+
@pytest.mark.asyncio
23+
async def test_egg_processes_ideas_with_matching_facts(temp_db):
24+
"""Test that egg processes Ideas and generates Facts when there are matching facts."""
25+
addr, engine, session = temp_db
26+
27+
# Add test data - a fact and an idea that should match
28+
async with session() as sess:
29+
# Add a fact that defines an equality
30+
sess.add(Facts(data="----\n(binary == a b)\n"))
31+
# Add an idea that should match the fact
32+
sess.add(Ideas(data="----\n(binary == a b)\n"))
33+
await sess.commit()
34+
35+
# Run the main function with a timeout to avoid infinite loop
36+
task = asyncio.create_task(main(addr, engine, session))
37+
await asyncio.sleep(0.3) # Give it time to process
38+
task.cancel()
39+
try:
40+
await task
41+
except asyncio.CancelledError:
42+
pass
43+
44+
# Verify that the idea was processed (it should be removed from pool when matched)
45+
# The fact count should remain the same or increase
46+
async with session() as sess:
47+
facts = await sess.scalars(select(Facts))
48+
fact_count = len(facts.all())
49+
assert fact_count >= 1
50+
51+
52+
@pytest.mark.asyncio
53+
async def test_egg_adds_facts_from_search_results(temp_db):
54+
"""Test that egg adds new Facts generated from search results."""
55+
addr, engine, session = temp_db
56+
57+
# Add test data
58+
async with session() as sess:
59+
# Add a base fact
60+
sess.add(Facts(data="----\nx\n"))
61+
# Add an idea that won't immediately match (will stay in pool)
62+
sess.add(Ideas(data="----\ny\n"))
63+
await sess.commit()
64+
65+
# Run the main function with a timeout
66+
task = asyncio.create_task(main(addr, engine, session))
67+
await asyncio.sleep(0.3) # Give it time to process
68+
task.cancel()
69+
try:
70+
await task
71+
except asyncio.CancelledError:
72+
pass
73+
74+
# Verify that facts were processed
75+
async with session() as sess:
76+
facts = await sess.scalars(select(Facts))
77+
fact_list = facts.all()
78+
assert len(fact_list) >= 1
79+
80+
81+
@pytest.mark.asyncio
82+
async def test_egg_with_multiple_ideas_and_facts(temp_db):
83+
"""Test that egg handles multiple Ideas and Facts correctly."""
84+
addr, engine, session = temp_db
85+
86+
# Add test data
87+
async with session() as sess:
88+
sess.add(Facts(data="----\na\n"))
89+
sess.add(Facts(data="----\nb\n"))
90+
sess.add(Ideas(data="----\nx\n"))
91+
sess.add(Ideas(data="----\ny\n"))
92+
await sess.commit()
93+
94+
# Run the main function with a timeout
95+
task = asyncio.create_task(main(addr, engine, session))
96+
await asyncio.sleep(0.3) # Give it time to process
97+
task.cancel()
98+
try:
99+
await task
100+
except asyncio.CancelledError:
101+
pass
102+
103+
# Verify that the system processed the data
104+
async with session() as sess:
105+
ideas = await sess.scalars(select(Ideas))
106+
facts = await sess.scalars(select(Facts))
107+
idea_list = ideas.all()
108+
fact_list = facts.all()
109+
assert len(idea_list) == 2 # Ideas should remain
110+
assert len(fact_list) >= 2 # Facts should be present
111+
112+
113+
@pytest.mark.asyncio
114+
async def test_egg_cancellation(temp_db):
115+
"""Test that the egg main function can be cancelled without hanging."""
116+
addr, engine, session = temp_db
117+
118+
# Run the main function and cancel it
119+
task = asyncio.create_task(main(addr, engine, session))
120+
await asyncio.sleep(0.1) # Let it start
121+
task.cancel()
122+
123+
# Should complete without hanging
124+
try:
125+
await task
126+
except asyncio.CancelledError:
127+
pass # Expected - cancellation worked
128+
129+
130+
@pytest.mark.asyncio
131+
async def test_egg_loop_continues_processing(temp_db):
132+
"""Test that egg continues looping and processing new data."""
133+
addr, engine, session = temp_db
134+
135+
# Add initial data
136+
async with session() as sess:
137+
sess.add(Facts(data="----\ninitial\n"))
138+
await sess.commit()
139+
140+
# Run the main function
141+
task = asyncio.create_task(main(addr, engine, session))
142+
await asyncio.sleep(0.2) # Let it process initial data
143+
144+
# Add more data while it's running
145+
async with session() as sess:
146+
sess.add(Ideas(data="----\nnew_idea\n"))
147+
await sess.commit()
148+
149+
await asyncio.sleep(0.2) # Give it time to process new data
150+
task.cancel()
151+
try:
152+
await task
153+
except asyncio.CancelledError:
154+
pass
155+
156+
# Verify that new data was processed
157+
async with session() as sess:
158+
ideas_result = await sess.scalars(select(Ideas))
159+
idea_list = ideas_result.all()
160+
assert len(idea_list) >= 1
161+
162+
163+
@pytest.mark.asyncio
164+
async def test_egg_incremental_processing(temp_db):
165+
"""Test that egg only processes new Facts and Ideas (using id > max_fact/max_idea)."""
166+
addr, engine, session = temp_db
167+
168+
# Add initial data
169+
async with session() as sess:
170+
sess.add(Facts(data="----\nfact1\n"))
171+
sess.add(Ideas(data="----\nidea1\n"))
172+
await sess.commit()
173+
174+
# Run the main function briefly
175+
task = asyncio.create_task(main(addr, engine, session))
176+
await asyncio.sleep(0.2)
177+
task.cancel()
178+
try:
179+
await task
180+
except asyncio.CancelledError:
181+
pass
182+
183+
# Add more data with higher IDs
184+
async with session() as sess:
185+
sess.add(Facts(data="----\nfact2\n"))
186+
sess.add(Ideas(data="----\nidea2\n"))
187+
await sess.commit()
188+
189+
# Run again - it should process the new data
190+
task = asyncio.create_task(main(addr, engine, session))
191+
await asyncio.sleep(0.2)
192+
task.cancel()
193+
try:
194+
await task
195+
except asyncio.CancelledError:
196+
pass
197+
198+
# Verify all data is in database
199+
async with session() as sess:
200+
facts_result = await sess.scalars(select(Facts))
201+
ideas_result = await sess.scalars(select(Ideas))
202+
assert len(facts_result.all()) >= 2
203+
assert len(ideas_result.all()) >= 2

0 commit comments

Comments
 (0)