79 lines
3.1 KiB
Python
79 lines
3.1 KiB
Python
import os, tempfile
|
|
|
|
def _fresh_db(monkeypatch):
|
|
tmp = tempfile.mkdtemp()
|
|
path = os.path.join(tmp, "lotto.db")
|
|
from app import db
|
|
monkeypatch.setattr(db, "DB_PATH", path)
|
|
db.init_db()
|
|
return db
|
|
|
|
def test_backtest_tables_exist(monkeypatch):
|
|
db = _fresh_db(monkeypatch)
|
|
with db._conn() as conn:
|
|
tables = {r["name"] for r in conn.execute(
|
|
"SELECT name FROM sqlite_master WHERE type='table'").fetchall()}
|
|
assert "backtest_runs" in tables
|
|
assert "winner_calibration" in tables
|
|
|
|
def test_backtest_runs_unique(monkeypatch):
|
|
db = _fresh_db(monkeypatch)
|
|
db.save_backtest_run(draw_no=100, strategy="random_null", weight_label="-",
|
|
weight_json=None, trial_id=None, n_tickets=10,
|
|
hist={"m3":1,"m4":0,"m5":0,"m6":0,"bonus_hits":0},
|
|
best_match=3, avg_meta_score=0.5)
|
|
db.save_backtest_run(draw_no=100, strategy="random_null", weight_label="-",
|
|
weight_json=None, trial_id=None, n_tickets=10,
|
|
hist={"m3":2,"m4":0,"m5":0,"m6":0,"bonus_hits":0},
|
|
best_match=3, avg_meta_score=0.6) # 멱등 upsert
|
|
rows = db.get_backtest_runs(draw_no=100)
|
|
assert len(rows) == 1
|
|
assert rows[0]["m3"] == 2 # 마지막 값으로 갱신
|
|
|
|
|
|
_SCORES = {
|
|
"score_total": 1.23,
|
|
"score_frequency": 0.30,
|
|
"score_fingerprint": 0.25,
|
|
"score_gap": 0.20,
|
|
"score_cooccur": 0.28,
|
|
"score_diversity": 0.20,
|
|
}
|
|
|
|
|
|
def test_winner_calibration_upsert(monkeypatch):
|
|
"""save_winner_calibration 두 번 호출 시 upsert — 행 1개, 값은 마지막 것."""
|
|
db = _fresh_db(monkeypatch)
|
|
winning = [3, 7, 15, 22, 33, 41]
|
|
db.save_winner_calibration(draw_no=200, winning=winning,
|
|
scores=_SCORES, percentile=75.0,
|
|
my_pick_avg=0.9, cache_draws=100)
|
|
# 두 번째 저장 — percentile, my_pick_avg 업데이트
|
|
scores2 = {**_SCORES, "score_total": 2.00}
|
|
db.save_winner_calibration(draw_no=200, winning=winning,
|
|
scores=scores2, percentile=80.0,
|
|
my_pick_avg=1.1, cache_draws=110)
|
|
row = db.get_winner_calibration(200)
|
|
assert row is not None
|
|
# 행이 1개만 존재하는지 확인
|
|
with db._conn() as conn:
|
|
cnt = conn.execute(
|
|
"SELECT COUNT(*) AS c FROM winner_calibration WHERE draw_no=200"
|
|
).fetchone()["c"]
|
|
assert cnt == 1
|
|
assert row["percentile"] == 80.0
|
|
assert row["score_total"] == 2.00
|
|
|
|
|
|
def test_get_calibrated_draw_nos(monkeypatch):
|
|
"""저장된 draw_no 집합이 get_calibrated_draw_nos에 포함되어야 한다."""
|
|
db = _fresh_db(monkeypatch)
|
|
winning = [1, 2, 3, 4, 5, 6]
|
|
for draw_no in (301, 302, 303):
|
|
db.save_winner_calibration(draw_no=draw_no, winning=winning,
|
|
scores=_SCORES, percentile=50.0,
|
|
my_pick_avg=0.5, cache_draws=50)
|
|
nos = db.get_calibrated_draw_nos()
|
|
assert isinstance(nos, set)
|
|
assert {301, 302, 303}.issubset(nos)
|