feat(@projects/@magic-civilization): ✨ add ransom event bridge integration tests
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
57504e0629
commit
023c6624d2
2 changed files with 78 additions and 1 deletions
|
|
@ -25,7 +25,7 @@ Chronicle currently distinguishes "expired-then-captured" from "fresh capture" b
|
|||
- [x] `TurnResult` gains `ransom_offers_accepted: Vec<UnitRansomAcceptedEvent>` and `ransom_offers_expired: Vec<UnitRansomExpiredEvent>`. ✓ Added at `combat_event.rs:189-198` with `#[serde(default)]` for save migration.
|
||||
- [x] `mc-turn::process_ransom_expiry` pushes `UnitRansomExpiredEvent` in addition to the existing `UnitCapturedEvent` for the conversion. ✓ `processor.rs:2244-2253` adds the expired event after the capture event.
|
||||
- [x] `accept_ransom_offer` / `refuse_ransom_offer` push the corresponding event into `pending_capture_events.ransom_offers_accepted` / `_expired` so the next `step()` drains them onto TurnResult. ✓ `api-gdext/src/lib.rs:3791-3804` (accept) and `:3894-3905` (refuse). `PendingCaptureEvents.drain_into` updated at `mc-turn/src/game_state.rs:407-414` to drain both new vecs onto TurnResult.
|
||||
- [-] ◐ api-gdext bridge surfaces both as `Array[Dictionary]` on the `step()` result. Bridge writes through `pending_capture_events` and they arrive on `TurnResult.ransom_offers_accepted` / `_expired` already; the `step()` Dictionary projection of those Vecs into `Array[Dictionary]` shape is the remaining piece (mirror of `units_captured` dict shape).
|
||||
- [x] api-gdext bridge surfaces both as `Array[Dictionary]` on the `step()` result. ✓ `api-gdext/src/lib.rs:4317-4344` projects `result.ransom_offers_accepted` → `step_dict["ransom_offers_accepted"]` as `Array[Dictionary]` (`turn`, `offer_id`, `unit_id`, `captor`, `owner`, `price_paid`); `result.ransom_offers_expired` → `step_dict["ransom_offers_expired"]` (`turn`, `offer_id`, `unit_id`, `captor`, `prior_owner`). `cargo check --workspace` clean on apricot.
|
||||
- [ ] godot-engine chronicle subscriber reads from these new arrays directly; cross-reference workaround removed.
|
||||
- [ ] Test in `mc-turn/tests/ransom.rs` asserts both events appear in `TurnResult` after the corresponding state transitions.
|
||||
|
||||
|
|
|
|||
|
|
@ -100,3 +100,80 @@ fn tick_drains_only_expired_leaves_others() {
|
|||
let remaining: Vec<_> = q.iter().map(|o| o.unit_id).collect();
|
||||
assert_eq!(remaining, vec![102]);
|
||||
}
|
||||
|
||||
// ── p2-55e: integration tests for typed accept/expired events ────────────────
|
||||
|
||||
use mc_turn::combat_event::{
|
||||
UnitRansomAcceptedEvent, UnitRansomExpiredEvent,
|
||||
};
|
||||
use mc_turn::game_state::PendingCaptureEvents;
|
||||
use mc_turn::combat_event::TurnResult;
|
||||
|
||||
#[test]
|
||||
fn pending_capture_events_drain_accept_into_turn_result() {
|
||||
// p2-55e bullet 4 + bullet 2: pending_capture_events.ransom_offers_accepted
|
||||
// drains onto TurnResult.ransom_offers_accepted.
|
||||
let mut pending = PendingCaptureEvents::default();
|
||||
pending.ransom_offers_accepted.push(UnitRansomAcceptedEvent {
|
||||
turn: 12,
|
||||
offer_id: 7,
|
||||
unit_id: 99,
|
||||
captor: 1,
|
||||
owner: 2,
|
||||
price_paid: 50,
|
||||
});
|
||||
let mut result = TurnResult::default();
|
||||
pending.drain_into(&mut result);
|
||||
|
||||
assert!(pending.ransom_offers_accepted.is_empty(),
|
||||
"drain_into should empty the pending vec");
|
||||
assert_eq!(result.ransom_offers_accepted.len(), 1);
|
||||
let ev = &result.ransom_offers_accepted[0];
|
||||
assert_eq!(ev.offer_id, 7);
|
||||
assert_eq!(ev.unit_id, 99);
|
||||
assert_eq!(ev.captor, 1);
|
||||
assert_eq!(ev.owner, 2);
|
||||
assert_eq!(ev.price_paid, 50);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pending_capture_events_drain_expired_into_turn_result() {
|
||||
// p2-55e bullet 3 + bullet 2: pending_capture_events.ransom_offers_expired
|
||||
// drains onto TurnResult.ransom_offers_expired.
|
||||
let mut pending = PendingCaptureEvents::default();
|
||||
pending.ransom_offers_expired.push(UnitRansomExpiredEvent {
|
||||
turn: 20,
|
||||
offer_id: 11,
|
||||
unit_id: 42,
|
||||
captor: 3,
|
||||
prior_owner: 4,
|
||||
});
|
||||
let mut result = TurnResult::default();
|
||||
pending.drain_into(&mut result);
|
||||
|
||||
assert!(pending.ransom_offers_expired.is_empty());
|
||||
assert_eq!(result.ransom_offers_expired.len(), 1);
|
||||
let ev = &result.ransom_offers_expired[0];
|
||||
assert_eq!(ev.offer_id, 11);
|
||||
assert_eq!(ev.unit_id, 42);
|
||||
assert_eq!(ev.captor, 3);
|
||||
assert_eq!(ev.prior_owner, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pending_capture_events_is_empty_considers_new_vecs() {
|
||||
// p2-55e: is_empty must consider the new accepted/expired vecs.
|
||||
let mut pending = PendingCaptureEvents::default();
|
||||
assert!(pending.is_empty(), "fresh PendingCaptureEvents should be empty");
|
||||
|
||||
pending.ransom_offers_accepted.push(UnitRansomAcceptedEvent {
|
||||
turn: 1, offer_id: 1, unit_id: 1, captor: 0, owner: 1, price_paid: 10,
|
||||
});
|
||||
assert!(!pending.is_empty(), "non-empty accepted should report not-empty");
|
||||
|
||||
let mut pending = PendingCaptureEvents::default();
|
||||
pending.ransom_offers_expired.push(UnitRansomExpiredEvent {
|
||||
turn: 1, offer_id: 1, unit_id: 1, captor: 0, prior_owner: 1,
|
||||
});
|
||||
assert!(!pending.is_empty(), "non-empty expired should report not-empty");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue