Files
settled-reach/server/tests/serialization.rs
T
jpmschweitzerandClaude Opus 4.6 112910df9b test(simulation): expand test coverage per PR #2 review
- Add roundtrip tests for all PlayerAction variants (Hoshe #6)
- Add roundtrip tests for all EntityKind variants (Hoshe #6)
- Add day wraparound at midnight edge case test (Hoshe #7)
- Add day() calculation test (Hoshe #7)
- Add out-of-order input rejection test (Hoshe #7)
- Total: 15 → 20 tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 17:53:16 +01:00

107 lines
3.2 KiB
Rust

//! IPC serialization round-trip tests (D-030 Layer 1: fixture-based).
use settled_reach_server::bridge::types::*;
#[test]
fn observer_snapshot_roundtrip() {
let snapshot = ObserverSnapshot {
tick: 42,
entities: vec![VisibleEntity {
entity_id: 1,
x: 10.0,
y: 20.0,
z: 0,
kind: EntityKind::Npc,
}],
};
let bytes = rmp_serde::to_vec(&snapshot).expect("serialize");
let decoded: ObserverSnapshot = rmp_serde::from_slice(&bytes).expect("deserialize");
assert_eq!(decoded.tick, 42);
assert_eq!(decoded.entities.len(), 1);
assert_eq!(decoded.entities[0].entity_id, 1);
}
#[test]
fn player_input_roundtrip() {
let input = PlayerInput {
tick: 100,
action: PlayerAction::MoveNorth,
};
let bytes = rmp_serde::to_vec(&input).expect("serialize");
let decoded: PlayerInput = rmp_serde::from_slice(&bytes).expect("deserialize");
assert_eq!(decoded.tick, 100);
}
#[test]
fn empty_snapshot_roundtrip() {
let snapshot = ObserverSnapshot {
tick: 0,
entities: vec![],
};
let bytes = rmp_serde::to_vec(&snapshot).expect("serialize");
let decoded: ObserverSnapshot = rmp_serde::from_slice(&bytes).expect("deserialize");
assert_eq!(decoded.tick, 0);
assert!(decoded.entities.is_empty());
}
/// All PlayerAction variants must survive MessagePack round-trip (D-030 Layer 1)
#[test]
fn all_player_action_variants_roundtrip() {
let actions = vec![
PlayerAction::MoveNorth,
PlayerAction::MoveSouth,
PlayerAction::MoveEast,
PlayerAction::MoveWest,
PlayerAction::Interact,
PlayerAction::UsePerceptionMode("thermal".to_string()),
PlayerAction::Pause,
PlayerAction::Unpause,
];
for action in actions {
let input = PlayerInput {
tick: 1,
action: action.clone(),
};
let bytes = rmp_serde::to_vec(&input).expect("serialize");
let decoded: PlayerInput = rmp_serde::from_slice(&bytes).expect("deserialize");
assert_eq!(decoded.tick, 1);
// Verify the variant survived by re-serializing and comparing bytes
let re_bytes = rmp_serde::to_vec(&decoded).expect("re-serialize");
assert_eq!(bytes, re_bytes, "round-trip mismatch for action variant");
}
}
/// All EntityKind variants must survive MessagePack round-trip (D-030 Layer 1)
#[test]
fn all_entity_kind_variants_roundtrip() {
let kinds = vec![EntityKind::Npc, EntityKind::Object, EntityKind::Terrain];
for (i, kind) in kinds.into_iter().enumerate() {
let entity = VisibleEntity {
entity_id: i as u64,
x: 0.0,
y: 0.0,
z: 0,
kind,
};
let snapshot = ObserverSnapshot {
tick: 0,
entities: vec![entity],
};
let bytes = rmp_serde::to_vec(&snapshot).expect("serialize");
let decoded: ObserverSnapshot = rmp_serde::from_slice(&bytes).expect("deserialize");
let re_bytes = rmp_serde::to_vec(&decoded).expect("re-serialize");
assert_eq!(
bytes, re_bytes,
"round-trip mismatch for EntityKind variant"
);
}
}