"""Phase 2 PoC #4 — risk_composite DEFAULT_PARAMS ↔ seed SQL 정적 일치 테스트.""" from __future__ import annotations import importlib import json import os import sys import types import unittest if 'pandas' not in sys.modules: pd_stub = types.ModuleType('pandas') pd_stub.DataFrame = type('DataFrame', (), {}) pd_stub.Timestamp = type('Timestamp', (), {}) sys.modules['pandas'] = pd_stub if 'pydantic_settings' not in sys.modules: stub = types.ModuleType('pydantic_settings') class _S: def __init__(self, **kw): for name, value in self.__class__.__dict__.items(): if name.isupper(): setattr(self, name, kw.get(name, value)) stub.BaseSettings = _S sys.modules['pydantic_settings'] = stub if 'algorithms' not in sys.modules: pkg = types.ModuleType('algorithms') pkg.__path__ = [os.path.join(os.path.dirname(__file__), '..', 'algorithms')] sys.modules['algorithms'] = pkg # risk.py 는 algorithms.location/fishing_pattern/dark_vessel/spoofing 을 top-level # import 한다. dark_vessel 만 실제 모듈 그대로 두고 나머지는 필요한 심볼만 stub. if 'algorithms.location' in sys.modules: if not hasattr(sys.modules['algorithms.location'], 'classify_zone'): sys.modules['algorithms.location'].classify_zone = lambda *a, **k: {} else: loc = types.ModuleType('algorithms.location') loc.haversine_nm = lambda a, b, c, d: 0.0 loc.classify_zone = lambda *a, **k: {} sys.modules['algorithms.location'] = loc for mod_name, attrs in [ ('algorithms.fishing_pattern', ['detect_fishing_segments', 'detect_trawl_uturn']), ('algorithms.spoofing', ['detect_teleportation', 'count_speed_jumps']), ]: if mod_name not in sys.modules: m = types.ModuleType(mod_name) sys.modules[mod_name] = m m = sys.modules[mod_name] for a in attrs: if not hasattr(m, a): setattr(m, a, lambda *_a, **_kw: []) class RiskCompositeParamsTest(unittest.TestCase): def test_seed_matches_default(self): risk = importlib.import_module('algorithms.risk') seed_path = os.path.join( os.path.dirname(__file__), '..', 'models_core', 'seeds', 'v1_risk_composite.sql', ) with open(seed_path, 'r', encoding='utf-8') as f: sql = f.read() start = sql.index('$json$') + len('$json$') end = sql.index('$json$', start) params = json.loads(sql[start:end].strip()) self.assertEqual(params, risk.RISK_COMPOSITE_DEFAULT_PARAMS) if __name__ == '__main__': unittest.main()