forked from 1b-agent/opencadstudio-upstream
test(flatten): add golden, filter, invariant, and differential regression tests
11 tests in tests/flatten_regression.rs: projection goldens (line/circle/polyline3d/polyline2d/text/solid), None cases, locked-layer/selection/space collection filters, plan/apply invariants, legacy-loop differential. Adds 2 ring-depth tests in src/scene/mod.rs pinning update_entities' collapsed block-sentinel delta (legacy 2 vs batch 1, final-state equality).
This commit is contained in:
1 parent
91900c4e73
commit
f4dfead9c0
2 files changed
+352
No files matched your search
@@ -13686,3 +13686,134 @@ mod layout_cache_tests {
|
||||
assert!(after.iter().any(|(n, _, _)| n == "1:50"));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod update_entities_batch_tests {
|
||||
use super::Scene;
|
||||
use codec::entities::{Block, BlockEnd, Line};
|
||||
use codec::types::Vector3;
|
||||
use codec::{EntityType, Handle};
|
||||
|
||||
/// Fresh scene holding two block sentinels (Block + BlockEnd) and one plain
|
||||
/// line; returns their handles in that order.
|
||||
fn scene_with_sentinels_and_line() -> (Scene, Handle, Handle, Handle) {
|
||||
let mut scene = Scene::new();
|
||||
let bh = scene
|
||||
.document
|
||||
.add_entity(EntityType::Block(Block::new("BATCH_TEST", Vector3::ZERO)))
|
||||
.unwrap();
|
||||
let be = scene
|
||||
.document
|
||||
.add_entity(EntityType::BlockEnd(BlockEnd::new()))
|
||||
.unwrap();
|
||||
let mut line = Line::new();
|
||||
line.start = Vector3::new(0.0, 0.0, 1.0);
|
||||
line.end = Vector3::new(3.0, 4.0, 2.0);
|
||||
let lh = scene.document.add_entity(EntityType::Line(line)).unwrap();
|
||||
(scene, bh, be, lh)
|
||||
}
|
||||
|
||||
/// Stored entity as-is — the update shape the command arms actually pass.
|
||||
fn snapshot(scene: &Scene, handle: Handle) -> EntityType {
|
||||
scene.document.get_entity(handle).unwrap().clone()
|
||||
}
|
||||
|
||||
/// The same line with an edited Z, still carrying its original handle.
|
||||
fn edited_line(scene: &Scene, handle: Handle) -> EntityType {
|
||||
let mut entity = snapshot(scene, handle);
|
||||
if let EntityType::Line(line) = &mut entity {
|
||||
line.start.z = 5.0;
|
||||
line.end.z = 6.0;
|
||||
}
|
||||
entity
|
||||
}
|
||||
|
||||
fn delta_count(scene: &Scene) -> usize {
|
||||
scene.geometry_deltas.borrow().len()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_entities_batch_of_block_sentinels_collapses_to_one_full_delta() {
|
||||
// Batched path: one coarse publish for the whole set.
|
||||
let (mut batched, bh, be, _) = scene_with_sentinels_and_line();
|
||||
let before = delta_count(&batched);
|
||||
let updates = vec![snapshot(&batched, bh), snapshot(&batched, be)];
|
||||
let moved = batched.update_entities(updates);
|
||||
assert_eq!(moved, 2);
|
||||
{
|
||||
let ring = batched.geometry_deltas.borrow();
|
||||
assert_eq!(
|
||||
ring.len() - before,
|
||||
1,
|
||||
"batched sentinels must publish exactly one geometry delta"
|
||||
);
|
||||
assert!(
|
||||
ring.back().unwrap().full,
|
||||
"the batched delta must be full (bump_geometry)"
|
||||
);
|
||||
}
|
||||
|
||||
// Legacy path: each sentinel bumps on its own.
|
||||
let (mut legacy, bh, be, _) = scene_with_sentinels_and_line();
|
||||
let before = delta_count(&legacy);
|
||||
let u1 = snapshot(&legacy, bh);
|
||||
let u2 = snapshot(&legacy, be);
|
||||
assert!(legacy.update_entity(u1));
|
||||
assert!(legacy.update_entity(u2));
|
||||
assert_eq!(
|
||||
delta_count(&legacy) - before,
|
||||
2,
|
||||
"legacy per-entity updates must publish one delta each"
|
||||
);
|
||||
|
||||
// Same final entity state either way.
|
||||
for h in [bh, be] {
|
||||
assert_eq!(
|
||||
format!("{:?}", batched.document.get_entity(h)),
|
||||
format!("{:?}", legacy.document.get_entity(h)),
|
||||
"entity {h:?} differs between batched and legacy updates"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_entities_mixed_batch_matches_legacy_states_with_one_coarse_delta() {
|
||||
// Batched: the sentinel's coarse (full) delta subsumes the line's
|
||||
// would-be per-entity delta, and both slots are still written.
|
||||
let (mut batched, bh, _, lh) = scene_with_sentinels_and_line();
|
||||
let before = delta_count(&batched);
|
||||
let updates = vec![snapshot(&batched, bh), edited_line(&batched, lh)];
|
||||
let moved = batched.update_entities(updates);
|
||||
assert_eq!(moved, 2);
|
||||
{
|
||||
let ring = batched.geometry_deltas.borrow();
|
||||
assert_eq!(
|
||||
ring.len() - before,
|
||||
1,
|
||||
"mixed batch with a sentinel must publish one coarse delta"
|
||||
);
|
||||
assert!(ring.back().unwrap().full, "coarse delta must be full");
|
||||
}
|
||||
|
||||
// Legacy: full delta for the sentinel + per-entity delta for the line.
|
||||
let (mut legacy, bh, _, lh) = scene_with_sentinels_and_line();
|
||||
let before = delta_count(&legacy);
|
||||
let u1 = snapshot(&legacy, bh);
|
||||
let u2 = edited_line(&legacy, lh);
|
||||
assert!(legacy.update_entity(u1));
|
||||
assert!(legacy.update_entity(u2));
|
||||
assert_eq!(
|
||||
delta_count(&legacy) - before,
|
||||
2,
|
||||
"legacy publishes one delta per update"
|
||||
);
|
||||
|
||||
for h in [bh, lh] {
|
||||
assert_eq!(
|
||||
format!("{:?}", batched.document.get_entity(h)),
|
||||
format!("{:?}", legacy.document.get_entity(h)),
|
||||
"entity {h:?} differs between batched and legacy updates"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user