"""ECR-002:runtime 门面公开符号 + 子模块可导入。""" from __future__ import annotations import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(ROOT)) sys.path.insert(0, str(ROOT / "web")) REQUIRED = [ "get_kl_data", "analyze_chan", "add_indicators", "serialize_chan_macd_data", "clean_dataframe_for_json", "classify_trend_stage", "refresh_data_service_metadata", "TIMEFRAMES", "SYMBOLS", "_zone_cache", "macd_fast_period", "is_smaller_or_equal_timeframe", "get_uncompleted_seg_list", ] def test_runtime_facade_exports(): from services import runtime as R for name in REQUIRED: assert hasattr(R, name), f"missing facade export: {name}" def test_runtime_submodules_importable(): from services.runtime import state, timeframes, market_data, indicators, analyze, serialize assert state.exchange is not None assert callable(timeframes.timeframe_to_minutes) assert callable(market_data.get_kl_data) assert callable(indicators.add_indicators) assert callable(analyze.analyze_chan) assert callable(serialize.convert_direction) def test_thin_shims_still_reexport(): from services import market_data as md from services import chan_analyze as ca from services import serializers as ser from services import timeframes as tf assert callable(md.get_kl_data) assert callable(ca.analyze_chan) assert callable(ser.serialize_chan_macd_data) assert callable(tf.timeframe_to_minutes)