86 lines
2.5 KiB
Rust
86 lines
2.5 KiB
Rust
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
//! Unit tests for the per-client desired-set diff.
|
|
|
|
use super::*;
|
|
use crate::world_server::cylinder_chunks;
|
|
|
|
/// Builds the streaming cylinder around `center` at `radius` as a set, mirroring what a subscription produces.
|
|
fn cylinder(center: ChunkPos, radius: i32) -> HashSet<ChunkPos> {
|
|
let mut set = HashSet::new();
|
|
cylinder_chunks(center, radius, &mut set);
|
|
set
|
|
}
|
|
|
|
#[test]
|
|
fn diff_of_equal_sets_is_empty() {
|
|
let set = cylinder(ChunkPos::new(0, 0, 0), 3);
|
|
let diff = desired_diff(&set, &set);
|
|
assert!(
|
|
diff.added.is_empty(),
|
|
"no chunks are added when the set is unchanged"
|
|
);
|
|
assert!(
|
|
diff.removed.is_empty(),
|
|
"no chunks are removed when the set is unchanged"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn from_empty_previous_adds_all_new() {
|
|
let new = cylinder(ChunkPos::new(5, 0, -2), 2);
|
|
let diff = desired_diff(&HashSet::new(), &new);
|
|
assert_eq!(
|
|
diff.added.len(),
|
|
new.len(),
|
|
"an initial subscribe adds the whole set"
|
|
);
|
|
assert!(
|
|
diff.removed.is_empty(),
|
|
"an initial subscribe removes nothing"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn center_move_by_one_chunk_swaps_symmetric_shells() {
|
|
let previous = cylinder(ChunkPos::new(0, 0, 0), 3);
|
|
let new = cylinder(ChunkPos::new(1, 0, 0), 3);
|
|
let diff = desired_diff(&previous, &new);
|
|
|
|
// Every added chunk is genuinely new; every removed chunk genuinely left.
|
|
for pos in &diff.added {
|
|
assert!(
|
|
new.contains(pos) && !previous.contains(pos),
|
|
"added chunks are new-only"
|
|
);
|
|
}
|
|
for pos in &diff.removed {
|
|
assert!(
|
|
previous.contains(pos) && !new.contains(pos),
|
|
"removed chunks are previous-only"
|
|
);
|
|
}
|
|
|
|
// A one-chunk shift keeps the overlap resident, so neither list is the whole set.
|
|
assert!(!diff.added.is_empty() && diff.added.len() < new.len());
|
|
assert!(!diff.removed.is_empty());
|
|
|
|
// The cylinder is translation-invariant in size, so a shift moves equal counts in and out.
|
|
assert_eq!(diff.added.len(), diff.removed.len());
|
|
}
|
|
|
|
#[test]
|
|
fn added_and_removed_are_sorted() {
|
|
let previous = cylinder(ChunkPos::new(0, 0, 0), 2);
|
|
let new = cylinder(ChunkPos::new(2, 1, 0), 2);
|
|
let diff = desired_diff(&previous, &new);
|
|
assert!(
|
|
diff.added.windows(2).all(|w| w[0] <= w[1]),
|
|
"added list is sorted"
|
|
);
|
|
assert!(
|
|
diff.removed.windows(2).all(|w| w[0] <= w[1]),
|
|
"removed list is sorted"
|
|
);
|
|
}
|