test: shape_forge 测试外移 overflow 四测留内联

This commit is contained in:
2026-09-16 00:36:08 +00:00
parent 61f590f118
commit db477c2776
2 changed files with 153 additions and 152 deletions
-152
View File
@@ -245,86 +245,6 @@ mod tests {
use super::*;
use std::sync::Barrier;
#[test]
fn empty_shape_exists() {
let forge = ShapeForge::new();
let s = forge.get_shape(EMPTY_SHAPE_ID);
assert!(s.is_some());
let s = s.unwrap();
assert_eq!(s.id, EMPTY_SHAPE_ID);
assert!(s.parent.is_none());
assert_eq!(s.depth, 0);
}
#[test]
fn make_shape_creates_new_id() {
let forge = ShapeForge::new();
let key: StringIndex = 1_000_000;
let s1 = forge.make_shape(EMPTY_SHAPE_ID, key);
assert!(s1 > EMPTY_SHAPE_ID);
let shape = forge.get_shape(s1).unwrap();
assert_eq!(shape.property_name, key);
assert_eq!(shape.parent, Some(EMPTY_SHAPE_ID));
assert_eq!(shape.depth, 1);
}
#[test]
fn hash_cons_returns_same_id() {
let forge = ShapeForge::new();
let key: StringIndex = 1_000_001;
let a = forge.make_shape(EMPTY_SHAPE_ID, key);
let b = forge.make_shape(EMPTY_SHAPE_ID, key);
assert_eq!(a, b);
}
#[test]
fn different_props_different_ids() {
let forge = ShapeForge::new();
let a = forge.make_shape(EMPTY_SHAPE_ID, 1_000_002);
let b = forge.make_shape(EMPTY_SHAPE_ID, 1_000_003);
assert_ne!(a, b);
}
#[test]
fn chain_of_three() {
let forge = ShapeForge::new();
let s1 = forge.make_shape(EMPTY_SHAPE_ID, 1_000_010);
let s2 = forge.make_shape(s1, 1_000_020);
let s3 = forge.make_shape(s2, 1_000_030);
assert_eq!(forge.shape_prop_count(s3), 3);
assert_eq!(forge.lookup_position(s3, 1_000_030), Some(2));
assert_eq!(forge.lookup_position(s3, 1_000_020), Some(1));
assert_eq!(forge.lookup_position(s3, 1_000_010), Some(0));
assert_eq!(forge.lookup_position(s3, 99), None);
}
#[test]
fn lookup_position_cached_second_call() {
let forge = ShapeForge::new();
let s1 = forge.make_shape(EMPTY_SHAPE_ID, 1_000_010);
let s2 = forge.make_shape(s1, 1_000_020);
let s3 = forge.make_shape(s2, 1_000_030);
// 首次调用填充缓存。
assert_eq!(forge.lookup_position(s3, 1_000_020), Some(1));
// 二次调用命中缓存(验证无回归)。
assert_eq!(forge.lookup_position(s3, 1_000_020), Some(1));
assert_eq!(forge.lookup_position(s3, 1_000_030), Some(2));
assert_eq!(forge.lookup_position(s3, 1_000_030), Some(2));
}
#[test]
fn clear_transient_clears_positions() {
let forge = ShapeForge::new();
let s1 = forge.make_shape(EMPTY_SHAPE_ID, 1_000_010);
assert_eq!(forge.lookup_position(s1, 1_000_010), Some(0));
forge.clear_transient();
// 清理后只剩 EMPTY_SHAPE,其余全部移除。
assert_eq!(forge.shapes.read().unwrap().len(), 1);
}
/// overflow 态复位钉:曾触发 overflow 后清空,overflow 标志与映射须一并清空,
/// 后续 make_shape 从新空间取小 id(而非旧 overflow 映射 id)。
#[test]
@@ -342,78 +262,6 @@ mod tests {
assert_eq!(id, 2);
}
#[test]
fn two_branches_share_ancestor() {
let forge = ShapeForge::new();
let base = forge.make_shape(EMPTY_SHAPE_ID, 1_000_040);
let branch_a = forge.make_shape(base, 1_000_050);
let branch_b = forge.make_shape(base, 1_000_060);
assert_ne!(branch_a, branch_b);
let a_shape = forge.get_shape(branch_a).unwrap();
let b_shape = forge.get_shape(branch_b).unwrap();
assert_eq!(a_shape.parent, Some(base));
assert_eq!(b_shape.parent, Some(base));
}
#[test]
fn edge_same_structure_different_names() {
let forge = ShapeForge::new();
let s1 = forge.make_shape(EMPTY_SHAPE_ID, 1_000_070);
let s2 = forge.make_shape(s1, 1_000_080);
let s3 = forge.make_shape(EMPTY_SHAPE_ID, 1_000_090);
let s4 = forge.make_shape(s3, 1_000_100);
assert_ne!(s1, s3);
assert_ne!(s2, s4);
assert_eq!(forge.lookup_position(s2, 1_000_070), Some(0));
assert_eq!(forge.lookup_position(s4, 1_000_090), Some(0));
}
#[test]
fn concurrent_make_same_key() {
let forge = Arc::new(ShapeForge::new());
let key: StringIndex = 1_000_200;
let barrier = Arc::new(Barrier::new(2));
let f1 = Arc::clone(&forge);
let b1 = Arc::clone(&barrier);
let h1 = std::thread::spawn(move || {
b1.wait();
f1.make_shape(EMPTY_SHAPE_ID, key)
});
let f2 = Arc::clone(&forge);
let b2 = Arc::clone(&barrier);
let h2 = std::thread::spawn(move || {
b2.wait();
f2.make_shape(EMPTY_SHAPE_ID, key)
});
let id1 = h1.join().unwrap();
let id2 = h2.join().unwrap();
assert_eq!(id1, id2);
assert!(id1 > EMPTY_SHAPE_ID);
}
#[test]
fn has_property_works() {
let forge = ShapeForge::new();
let s1 = forge.make_shape(EMPTY_SHAPE_ID, 1_000_300);
let s2 = forge.make_shape(s1, 1_000_310);
assert!(forge.has_property(s2, 1_000_300));
assert!(forge.has_property(s2, 1_000_310));
assert!(!forge.has_property(s2, 99));
}
#[test]
fn private_band_keys_are_shape_properties() {
let forge = ShapeForge::new();
let private_key = oxide_types::private_key::make_private_name_id(12);
let shape = forge.make_shape(EMPTY_SHAPE_ID, private_key);
assert!(oxide_types::private_key::is_private_name_key(private_key));
assert!(forge.has_property(shape, private_key));
assert_eq!(forge.lookup_position(shape, private_key), Some(0));
}
#[test]
#[cfg_attr(debug_assertions, should_panic(expected = "exceeds 24-bit"))]
fn overflow_debug_assert_fires() {