feat(client): add batch fixture, fixture smoke test, decode_errors test
Tyre #1: Added Rust-generated input_batch_two.msgpack fixture for bidirectional D-030 Layer 1 symmetry (Vec<PlayerInput>). Tyre #2: Added all_fixtures_deserialize Rust test that reads every .msgpack fixture and verifies it deserializes (corruption guard). Hoshe #3: Added test_decode_snapshot_malformed_entities_counted test verifying the decode_errors counter on D-010 boundary violations. 45 client tests, 54 server tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -115,6 +115,22 @@ fn generate_msgpack_fixtures() {
|
||||
&rmp_serde::to_vec_named(&snapshot_multi).unwrap(),
|
||||
);
|
||||
|
||||
// Batch input: Vec<PlayerInput> with two actions (D-030 Layer 1 bidirectional symmetry)
|
||||
let input_batch = vec![
|
||||
PlayerInput {
|
||||
tick: 0,
|
||||
action: PlayerAction::MoveNorth,
|
||||
},
|
||||
PlayerInput {
|
||||
tick: 0,
|
||||
action: PlayerAction::Interact,
|
||||
},
|
||||
];
|
||||
write_fixture(
|
||||
"input_batch_two",
|
||||
&rmp_serde::to_vec_named(&input_batch).unwrap(),
|
||||
);
|
||||
|
||||
// Diagonal movement fixtures (clockwise: NE, SE, SW, NW)
|
||||
for (name, action) in [
|
||||
("input_move_northeast", PlayerAction::MoveNortheast),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! IPC serialization round-trip tests (D-030 Layer 1: fixture-based).
|
||||
|
||||
use settled_reach_server::bridge::types::*;
|
||||
use std::fs;
|
||||
|
||||
#[test]
|
||||
fn observer_snapshot_roundtrip() {
|
||||
@@ -82,6 +83,46 @@ fn all_player_action_variants_roundtrip() {
|
||||
}
|
||||
}
|
||||
|
||||
/// All .msgpack fixtures must deserialize without error (guards against corruption in git).
|
||||
/// Snapshot fixtures deserialize as ObserverSnapshot, input_* as PlayerInput,
|
||||
/// input_batch_* as Vec<PlayerInput>.
|
||||
#[test]
|
||||
fn all_fixtures_deserialize() {
|
||||
let fixture_dir = std::path::Path::new("../client/tests/fixtures/msgpack");
|
||||
assert!(
|
||||
fixture_dir.exists(),
|
||||
"Fixture directory not found: {}",
|
||||
fixture_dir.display()
|
||||
);
|
||||
|
||||
let mut count = 0;
|
||||
for entry in fs::read_dir(fixture_dir).expect("read fixture dir") {
|
||||
let entry = entry.expect("read dir entry");
|
||||
let path = entry.path();
|
||||
if path.extension().and_then(|e| e.to_str()) != Some("msgpack") {
|
||||
continue;
|
||||
}
|
||||
let name = path.file_stem().unwrap().to_str().unwrap().to_string();
|
||||
let bytes = fs::read(&path).unwrap_or_else(|_| panic!("read fixture {}", name));
|
||||
|
||||
if name.starts_with("snapshot") {
|
||||
rmp_serde::from_slice::<ObserverSnapshot>(&bytes)
|
||||
.unwrap_or_else(|e| panic!("deserialize snapshot fixture {}: {}", name, e));
|
||||
} else if name.starts_with("input_batch") {
|
||||
rmp_serde::from_slice::<Vec<PlayerInput>>(&bytes)
|
||||
.unwrap_or_else(|e| panic!("deserialize batch input fixture {}: {}", name, e));
|
||||
} else if name.starts_with("input") {
|
||||
rmp_serde::from_slice::<PlayerInput>(&bytes)
|
||||
.unwrap_or_else(|e| panic!("deserialize input fixture {}: {}", name, e));
|
||||
} else {
|
||||
panic!("unknown fixture naming convention: {}", name);
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
assert!(count > 0, "no fixtures found");
|
||||
eprintln!("Verified {} fixtures", count);
|
||||
}
|
||||
|
||||
/// All EntityKind variants must survive MessagePack round-trip (D-030 Layer 1)
|
||||
#[test]
|
||||
fn all_entity_kind_variants_roundtrip() {
|
||||
|
||||
Reference in New Issue
Block a user