mirror of
https://ghfast.top/https://github.com/aeroxw/easy_tdx_max.git
synced 2026-09-12 14:34:18 +08:00
fix: 板块成分股/排行报价分页合并顺序颠倒 — 多页前插改按页序追加
BoardMembersQuotesCmd 分页合并曾用 batch + all_quotes 前插,而协议 start=0 返回排序后最前一页:成分股超过单页 80 只的板块(半导体 SH881319、 光学光电 SH881329、通信设备 SH881338 等)弹窗涨跌幅榜从第 81~100 名开头, 前 80 名被压到后面,肉眼即乱序;≤80 只的板块单页不受影响。 同步/异步 get_board_members 与 get_stock_quotes_list 共 4 处统一改为 按页序追加(all_quotes = all_quotes + batch),回归测试钉死多页合并顺序、 start 偏移推进与末页不足一页的终止行为。 注:test_ex_reconnect::test_all_retries_relogin_each_time 存量失败 (干净工作树同样失败),与本修复无关,另案处理。
This commit is contained in:
@@ -388,7 +388,7 @@ class MacClient:
|
||||
)
|
||||
if not batch:
|
||||
break
|
||||
all_quotes = batch + all_quotes
|
||||
all_quotes = all_quotes + batch
|
||||
fetched += len(batch)
|
||||
offset += len(batch)
|
||||
if len(batch) < page_size:
|
||||
@@ -799,7 +799,7 @@ class MacClient:
|
||||
)
|
||||
if not batch:
|
||||
break
|
||||
all_quotes = batch + all_quotes
|
||||
all_quotes = all_quotes + batch
|
||||
fetched += len(batch)
|
||||
offset += len(batch)
|
||||
if len(batch) < page_size:
|
||||
@@ -1448,7 +1448,7 @@ class AsyncMacClient(AsyncHeartbeatMixin):
|
||||
)
|
||||
if not batch:
|
||||
break
|
||||
all_quotes = batch + all_quotes
|
||||
all_quotes = all_quotes + batch
|
||||
fetched += len(batch)
|
||||
offset += len(batch)
|
||||
if len(batch) < page_size:
|
||||
@@ -1787,7 +1787,7 @@ class AsyncMacClient(AsyncHeartbeatMixin):
|
||||
)
|
||||
if not batch:
|
||||
break
|
||||
all_quotes = batch + all_quotes
|
||||
all_quotes = all_quotes + batch
|
||||
fetched += len(batch)
|
||||
offset += len(batch)
|
||||
if len(batch) < page_size:
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
"""成分股/排行报价分页合并顺序回归测试。
|
||||
|
||||
真实 bug(v1.32.x):BoardMembersQuotesCmd 分页合并曾用 ``batch + all_quotes``
|
||||
前插,而协议 ``start=0`` 返回排序后**最前**的一页——多页时整表被按页倒序拼接:
|
||||
成分股超过单页 80 只的板块(如半导体 SH881319),弹窗涨跌幅榜从第 81 名开头,
|
||||
前 80 名被压到后面,肉眼即"乱序"。
|
||||
|
||||
本测试钉死:多页合并必须按请求顺序追加,且 start 偏移正确推进。
|
||||
"""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from easy_tdx.mac.client import AsyncMacClient, MacClient
|
||||
from easy_tdx.mac.enums import SortOrder, SortType
|
||||
from easy_tdx.mac.models import MacQuoteField
|
||||
|
||||
_TOTAL = 100 # 超过单页 80,触发两页
|
||||
|
||||
|
||||
def _make_rows(start: int, n: int) -> list[MacQuoteField]:
|
||||
"""模拟服务器:按涨跌幅降序返回第 start..start+n 名。"""
|
||||
|
||||
def code(i: int) -> str:
|
||||
return f"{600000 + i:06d}"
|
||||
|
||||
return [
|
||||
MacQuoteField(
|
||||
market=1,
|
||||
code=code(i),
|
||||
name=f"股{i}",
|
||||
fields={"change_pct": 10.0 - i * 0.2},
|
||||
)
|
||||
for i in range(start, start + n)
|
||||
]
|
||||
|
||||
|
||||
def _fake_execute_factory(seen: list):
|
||||
def fake_execute(cmd):
|
||||
seen.append(cmd)
|
||||
# 真实服务器按剩余行数返回(末页不足 page_size),模拟之
|
||||
n = min(cmd._page_size, _TOTAL - cmd._start)
|
||||
return _make_rows(cmd._start, n)
|
||||
|
||||
return fake_execute
|
||||
|
||||
|
||||
def test_board_members_pages_appended_in_order():
|
||||
"""get_board_members 多页合并按页序追加:第 0 行=第 1 名,第 80 行=第 81 名。"""
|
||||
client = MacClient.__new__(MacClient)
|
||||
seen: list = []
|
||||
|
||||
with patch.object(client, "_execute", side_effect=_fake_execute_factory(seen)):
|
||||
df = client.get_board_members(
|
||||
"881319",
|
||||
count=_TOTAL,
|
||||
sort_type=SortType.CHANGE_PCT,
|
||||
sort_order=SortOrder.DESC,
|
||||
)
|
||||
|
||||
assert len(df) == _TOTAL
|
||||
assert df["code"].tolist() == [f"{600000 + i:06d}" for i in range(_TOTAL)]
|
||||
# 两页:start 0(80 行)→ start 80(20 行)
|
||||
assert [c._start for c in seen] == [0, 80]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_board_members_async_pages_appended_in_order():
|
||||
client = AsyncMacClient.__new__(AsyncMacClient)
|
||||
seen: list = []
|
||||
|
||||
async def fake_execute(cmd):
|
||||
seen.append(cmd)
|
||||
return _make_rows(cmd._start, cmd._page_size)
|
||||
|
||||
with patch.object(client, "_execute", side_effect=fake_execute):
|
||||
df = await client.get_board_members(
|
||||
"881319",
|
||||
count=_TOTAL,
|
||||
sort_type=SortType.CHANGE_PCT,
|
||||
sort_order=SortOrder.DESC,
|
||||
)
|
||||
|
||||
assert df["code"].tolist() == [f"{600000 + i:06d}" for i in range(_TOTAL)]
|
||||
assert [c._start for c in seen] == [0, 80]
|
||||
|
||||
|
||||
def test_quotes_list_pages_appended_in_order():
|
||||
"""get_stock_quotes_list(看板涨跌榜数据源)同样按页序追加。"""
|
||||
client = MacClient.__new__(MacClient)
|
||||
seen: list = []
|
||||
|
||||
with patch.object(client, "_execute", side_effect=_fake_execute_factory(seen)):
|
||||
df = client.get_stock_quotes_list(
|
||||
category=1, # Category.A
|
||||
count=_TOTAL,
|
||||
sort_type=SortType.CHANGE_PCT,
|
||||
sort_order=SortOrder.DESC,
|
||||
)
|
||||
|
||||
assert df["code"].tolist() == [f"{600000 + i:06d}" for i in range(_TOTAL)]
|
||||
assert [c._start for c in seen] == [0, 80]
|
||||
Reference in New Issue
Block a user