import pandas as pd from unittest.mock import patch, MagicMock from vnpy.trader.constant import Exchange, Interval from vnpy.trader.setting import SETTINGS from sanguo_data.config import DataConfig from sanguo_data.datareader import read_parquet_daily, guess_exchange, read_db_daily def test_read_parquet_daily_returns_bardata(tmp_path): year_dir = tmp_path / "2026" year_dir.mkdir() df = pd.DataFrame({ "date": ["2026-01-05", "2026-01-06"], "open": [10.0, 11.0], "high": [10.5, 11.5], "low": [9.8, 10.8], "close": [10.2, 11.2], "volume": [10000, 12000], }) df.to_parquet(year_dir / "sh600000_daily.parquet") # 实现读 {prefix}{symbol}_daily.parquet(line 24) cfg = DataConfig( data_paths={"daily_dir": str(tmp_path)}, data_sources={}, validation={}, performance={}, ) bars = read_parquet_daily("600000", "2026-01-01", "2026-12-31", cfg) assert len(bars) == 2 assert bars[0].symbol == "600000" assert bars[0].open_price == 10.0 def test_read_parquet_daily_dir_key_raw(tmp_path): """dir_key='raw_dir':切换到 raw 目录读真实价(task #79 双源)。""" raw_year = tmp_path / "2026" raw_year.mkdir() df = pd.DataFrame({ "date": ["2026-03-30"], "open": [9.97], "high": [10.05], "low": [9.95], "close": [10.01], "volume": [800000], }) df.to_parquet(raw_year / "sh600000_daily.parquet") # 真实文件名:sh 前缀 + _daily cfg = DataConfig( data_paths={"raw_dir": str(tmp_path)}, data_sources={}, validation={}, performance={}, ) bars = read_parquet_daily("600000", "2026-01-01", "2026-12-31", cfg, dir_key="raw_dir") assert len(bars) == 1 assert bars[0].close_price == 10.01 def test_guess_exchange_sh(): assert guess_exchange("600000").value == "SSE" def test_guess_exchange_sz(): assert guess_exchange("000001").value == "SZSE" def test_read_db_daily_configures_vnpy_settings(): """Test that read_db_daily configures vnpy SETTINGS with correct database path.""" cfg = DataConfig( data_paths={"vnpy_db": "/volume1/stock/sanguo_vnpy/data/quant_trading.db"}, data_sources={}, validation={}, performance={}, ) # Mock get_database to avoid actual database connection mock_db = MagicMock() mock_db.load_bar_data.return_value = [] # Return empty list to avoid data processing # read_db_daily 内部 lazy import(from vnpy.trader.database import get_database), # 故 patch 源模块属性,非 sanguo_data.datareader(其上无 get_database) with patch('vnpy.trader.database.get_database', return_value=mock_db): # Call read_db_daily read_db_daily("600000", "2024-01-01", "2024-12-31", cfg) # Assert that SETTINGS was configured correctly assert SETTINGS["database.name"] == "sqlite", f"Expected database.name to be 'sqlite', got {SETTINGS.get('database.name')}" assert SETTINGS["database.database"] == cfg.data_paths["vnpy_db"], f"Expected database.database to be {cfg.data_paths['vnpy_db']}, got {SETTINGS.get('database.database')}"