Synvael/crates/shared/src/tests/record.rs

71 lines
2 KiB
Rust

// SPDX-License-Identifier: AGPL-3.0-only
use super::*;
use crate::world::{BlockId, ChunkPos};
/// Builds a representative modified chunk with a few edits spanning the local index range.
fn sample() -> ChunkData {
let mut data = ChunkData::new(ChunkPos::new(1, -2, 3), 7);
data.set(0, BlockId(4));
data.set(1000, BlockId(9));
data.set(32_767, BlockId(2));
data
}
#[test]
fn round_trips_payload_and_metadata() -> Result<(), SaveError> {
let data = sample();
let bytes = encode(&data, 123_456)?;
let (meta, decoded) = decode(&bytes)?;
assert_eq!(decoded, data);
assert_eq!(meta.chunk_format_version, CHUNK_FORMAT_VERSION);
assert_eq!(meta.flags, 0);
assert_eq!(meta.last_modified, 123_456);
Ok(())
}
#[test]
fn rejects_bad_magic() -> Result<(), SaveError> {
let mut bytes = encode(&sample(), 0)?;
bytes[0] = b'X';
assert!(matches!(decode(&bytes), Err(SaveError::BadMagic { .. })));
Ok(())
}
#[test]
fn rejects_truncated_header() -> Result<(), SaveError> {
let bytes = encode(&sample(), 0)?;
// A buffer shorter than the fixed header cannot yield a full record.
assert!(matches!(
decode(&bytes[..HEADER_LEN - 1]),
Err(SaveError::Truncated { .. })
));
Ok(())
}
#[test]
fn rejects_truncated_payload() -> Result<(), SaveError> {
let bytes = encode(&sample(), 0)?;
// Keep the whole header but cut the compressed payload short.
assert!(matches!(
decode(&bytes[..=HEADER_LEN]),
Err(SaveError::Truncated { .. })
));
Ok(())
}
#[test]
fn detects_declared_length_mismatch() -> Result<(), SaveError> {
let mut bytes = encode(&sample(), 0)?;
// The uncompressed-length field is the u32 at offset 16 (after magic, version,
// flags, and the timestamp). Overwriting it with a value the payload cannot
// decompress to must be caught by the post-decompression length check.
bytes[16..20].copy_from_slice(&1u32.to_le_bytes());
assert!(matches!(
decode(&bytes),
Err(SaveError::LengthMismatch { .. })
));
Ok(())
}