lotto-lab: 구매 CRUD 확장 + strategy_performance/weights CRUD 추가
- _purchase_row_to_dict: numbers/is_real/source_detail/results/total_prize 신규 컬럼 포함 - add_purchase: numbers, is_real, source_strategy, source_detail 파라미터 추가 - get_purchases: is_real, strategy, checked 필터 추가 - get_purchase_stats: total/real/virtual/by_strategy 분리 통계 + 하위호환 필드 유지 - update_purchase: allowed 셋에 numbers/is_real/source_strategy 추가 - 신규: upsert_strategy_performance, get_strategy_performance - 신규: get_strategy_weights, update_strategy_weight - 신규: update_purchase_results (체커 연동용) - 테스트 5건 추가 (TDD) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -67,3 +67,132 @@ def test_strategy_weights_table_exists():
|
||||
total_weight = sum(r["weight"] for r in rows)
|
||||
assert abs(total_weight - 1.0) < 0.01
|
||||
mem.close()
|
||||
|
||||
|
||||
def test_add_purchase_with_numbers():
|
||||
"""번호 포함 구매 등록"""
|
||||
import db
|
||||
mem = _make_mem_conn()
|
||||
with patch("db._conn", return_value=mem):
|
||||
db.init_db()
|
||||
result = db.add_purchase(
|
||||
draw_no=1150,
|
||||
amount=5000,
|
||||
sets=5,
|
||||
numbers=[[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]],
|
||||
is_real=False,
|
||||
source_strategy="simulation",
|
||||
source_detail={"run_id": 42},
|
||||
)
|
||||
assert result["draw_no"] == 1150
|
||||
assert result["amount"] == 5000
|
||||
assert result["is_real"] == 0
|
||||
assert result["source_strategy"] == "simulation"
|
||||
assert result["numbers"] == [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
|
||||
assert result["source_detail"] == {"run_id": 42}
|
||||
mem.close()
|
||||
|
||||
|
||||
def test_get_purchases_filter_is_real():
|
||||
"""is_real 필터 동작"""
|
||||
import db
|
||||
mem = _make_mem_conn()
|
||||
with patch("db._conn", return_value=mem):
|
||||
db.init_db()
|
||||
db.add_purchase(draw_no=1150, amount=5000, sets=5, is_real=True)
|
||||
db.add_purchase(draw_no=1150, amount=1000, sets=1, is_real=False)
|
||||
real_only = db.get_purchases(is_real=True)
|
||||
virtual_only = db.get_purchases(is_real=False)
|
||||
assert len(real_only) == 1
|
||||
assert real_only[0]["is_real"] == 1
|
||||
assert len(virtual_only) == 1
|
||||
assert virtual_only[0]["is_real"] == 0
|
||||
mem.close()
|
||||
|
||||
|
||||
def test_get_purchase_stats_by_type():
|
||||
"""실제/가상 분리 통계"""
|
||||
import db
|
||||
mem = _make_mem_conn()
|
||||
with patch("db._conn", return_value=mem):
|
||||
db.init_db()
|
||||
db.add_purchase(draw_no=1150, amount=5000, sets=5, is_real=True, source_strategy="manual")
|
||||
db.add_purchase(draw_no=1150, amount=1000, sets=1, is_real=False, source_strategy="simulation")
|
||||
stats = db.get_purchase_stats()
|
||||
assert "total" in stats
|
||||
assert "real" in stats
|
||||
assert "virtual" in stats
|
||||
assert "by_strategy" in stats
|
||||
assert stats["total"]["sets"] == 6
|
||||
assert stats["real"]["sets"] == 5
|
||||
assert stats["virtual"]["sets"] == 1
|
||||
assert "manual" in stats["by_strategy"]
|
||||
assert "simulation" in stats["by_strategy"]
|
||||
# 하위호환 필드
|
||||
assert "total_records" in stats
|
||||
assert stats["total_records"] == 2
|
||||
mem.close()
|
||||
|
||||
|
||||
def test_upsert_strategy_performance():
|
||||
"""전략 성과 upsert"""
|
||||
import db
|
||||
mem = _make_mem_conn()
|
||||
with patch("db._conn", return_value=mem):
|
||||
db.init_db()
|
||||
# 최초 insert
|
||||
db.upsert_strategy_performance(
|
||||
strategy="simulation",
|
||||
draw_no=1150,
|
||||
sets_count=10,
|
||||
total_correct=30,
|
||||
max_correct=5,
|
||||
prize_total=5000,
|
||||
avg_score=3.0,
|
||||
)
|
||||
rows = db.get_strategy_performance(strategy="simulation")
|
||||
assert len(rows) == 1
|
||||
assert rows[0]["sets_count"] == 10
|
||||
assert rows[0]["avg_score"] == 3.0
|
||||
# upsert (동일 strategy+draw_no)
|
||||
db.upsert_strategy_performance(
|
||||
strategy="simulation",
|
||||
draw_no=1150,
|
||||
sets_count=20,
|
||||
total_correct=60,
|
||||
max_correct=6,
|
||||
prize_total=10000,
|
||||
avg_score=4.5,
|
||||
)
|
||||
rows = db.get_strategy_performance(strategy="simulation")
|
||||
assert len(rows) == 1 # 중복 없이 1개
|
||||
assert rows[0]["sets_count"] == 20
|
||||
assert rows[0]["avg_score"] == 4.5
|
||||
mem.close()
|
||||
|
||||
|
||||
def test_update_strategy_weight():
|
||||
"""전략 가중치 업데이트"""
|
||||
import db
|
||||
mem = _make_mem_conn()
|
||||
with patch("db._conn", return_value=mem):
|
||||
db.init_db()
|
||||
# 초기값 확인
|
||||
weights_before = db.get_strategy_weights()
|
||||
combined_before = next(w for w in weights_before if w["strategy"] == "combined")
|
||||
original_weight = combined_before["weight"]
|
||||
# 업데이트
|
||||
db.update_strategy_weight(
|
||||
strategy="combined",
|
||||
weight=0.5,
|
||||
ema_score=0.75,
|
||||
total_sets=100,
|
||||
total_hits_3plus=20,
|
||||
)
|
||||
weights_after = db.get_strategy_weights()
|
||||
combined_after = next(w for w in weights_after if w["strategy"] == "combined")
|
||||
assert combined_after["weight"] == 0.5
|
||||
assert combined_after["ema_score"] == 0.75
|
||||
assert combined_after["total_sets"] == 100
|
||||
assert combined_after["total_hits_3plus"] == 20
|
||||
mem.close()
|
||||
|
||||
Reference in New Issue
Block a user