严格校验换股证据并原子提交公司行为批次

This commit is contained in:
boris
2026-09-14 22:57:53 +08:00
parent d4e7cdd5b5
commit 59a0c95aae
5 changed files with 386 additions and 34 deletions
@@ -18,6 +18,10 @@ enum Action {
}
fn data(action: Action) -> DataSet {
data_with_successor_metadata(action, true)
}
fn data_with_successor_metadata(action: Action, include_successor: bool) -> DataSet {
let days = [10, 11, 14, 15].map(date);
let mut market = Vec::new();
let mut factors = Vec::new();
@@ -88,6 +92,7 @@ fn data(action: Action) -> DataSet {
DataSet::from_components_with_actions(
["000001.SZ", "000002.SZ"]
.into_iter()
.filter(|symbol| include_successor || *symbol != "000002.SZ")
.map(|symbol| Instrument {
symbol: symbol.into(),
name: symbol.into(),
@@ -280,6 +285,31 @@ fn delayed_sale_does_not_keep_unearned_corporate_entitlements() {
}
}
#[test]
fn paper_and_broker_observations_require_the_same_frozen_successor_scope() {
for adapter in ["paper", "gt", "qmt"] {
for delayed in [false, true] {
for sell in [false, true] {
let mut replay = source(delayed, sell);
for action in &mut replay.actions {
for order in &mut action.orders { order.source_adapter = Some(adapter.into()); }
}
replay.content_sha256 = replay.content_digest().unwrap();
replay.validate().unwrap();
let complete = run_custom(data(Action::Successor), replay.clone(), Hold, true, true).unwrap();
assert_eq!(complete.holdings_summary[0].symbol, "000002.SZ");
assert_eq!(complete.holdings_summary[0].quantity, 200);
assert!(complete.fills.is_empty());
assert!(complete.order_events.is_empty());
let error = run_custom(data_with_successor_metadata(Action::Successor, false),
replay, Hold, true, true).unwrap_err();
assert!(error.to_string().contains("successor_instrument_missing"),
"{adapter} delayed={delayed} sell={sell}: {error}");
}
}
}
}
#[test]
fn corporate_replay_preserves_issued_orders_cash_flows_financing_and_charged_fees() {
struct ExistingActivity {