Skip to content

Commit fe7134d

Browse files
anakrishCopilot
andcommitted
Add object frozen storage tests
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f391a5f commit fe7134d

1 file changed

Lines changed: 134 additions & 0 deletions

File tree

src/value/tests.rs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,3 +562,137 @@ fn object_insert_returns_previous_value() {
562562
assert_eq!(obj.insert(val(0), val(2)), Some(val(1)));
563563
assert_eq!(obj.get(&val(0)), Some(&val(2)));
564564
}
565+
566+
const CONST_OBJECT_NEW: Object = Object::new();
567+
568+
fn assert_all_objects_frozen(value: &Value) {
569+
match value {
570+
Value::Array(values) => {
571+
for value in values.iter() {
572+
assert_all_objects_frozen(value);
573+
}
574+
}
575+
Value::Set(values) => {
576+
for value in values.iter() {
577+
assert_all_objects_frozen(value);
578+
}
579+
}
580+
Value::Object(object) => {
581+
assert_eq!(object.storage_variant_for_memory_diagnostics(), "Frozen");
582+
for (_, value) in object.iter() {
583+
assert_all_objects_frozen(value);
584+
}
585+
}
586+
_ => {}
587+
}
588+
}
589+
590+
#[test]
591+
fn object_new_is_const_context() {
592+
assert!(CONST_OBJECT_NEW.is_empty());
593+
}
594+
595+
#[test]
596+
fn object_inline_cap_boundary_promotes_on_third_insert() {
597+
let mut obj = Object::new();
598+
obj.insert(val(1), val(10));
599+
obj.insert(val(2), val(20));
600+
assert_eq!(obj.storage_variant_for_memory_diagnostics(), "Inline");
601+
obj.insert(val(3), val(30));
602+
assert_eq!(obj.storage_variant_for_memory_diagnostics(), "BTree");
603+
}
604+
605+
#[test]
606+
fn object_btree_freeze_mutate_insert_and_refreeze_roundtrip() {
607+
let mut obj: Object = make_pairs(3).into_iter().collect();
608+
assert_eq!(obj.storage_variant_for_memory_diagnostics(), "BTree");
609+
obj = obj.freeze();
610+
assert_eq!(obj.storage_variant_for_memory_diagnostics(), "Frozen");
611+
obj.insert(val(99), val(100));
612+
assert_eq!(obj.storage_variant_for_memory_diagnostics(), "BTree");
613+
assert_eq!(obj.get(&val(99)), Some(&val(100)));
614+
obj = obj.freeze();
615+
assert_eq!(obj.storage_variant_for_memory_diagnostics(), "Frozen");
616+
assert_eq!(obj.get(&val(99)), Some(&val(100)));
617+
}
618+
619+
#[test]
620+
fn object_empty_freeze_get_iter_and_cursor() {
621+
let obj = Object::new().freeze();
622+
assert_eq!(obj.storage_variant_for_memory_diagnostics(), "Frozen");
623+
assert!(obj.get(&val(0)).is_none());
624+
assert_eq!(obj.iter().count(), 0);
625+
let mut cursor = obj.cursor();
626+
assert!(obj.next(&mut cursor).is_none());
627+
}
628+
629+
#[test]
630+
fn object_from_large_btreemap_into_value_is_frozen() {
631+
let map: BTreeMap<Value, Value> = make_pairs(3).into_iter().collect();
632+
let value = Object::from(map).into_value();
633+
let object = value.as_object().expect("object");
634+
assert_eq!(object.storage_variant_for_memory_diagnostics(), "Frozen");
635+
}
636+
637+
#[test]
638+
fn object_cross_variant_partial_eq_ignores_storage() {
639+
let empty_inline = Object::from_iter(core::iter::empty()).freeze();
640+
assert_eq!(Object::new(), empty_inline);
641+
642+
let inline: Object = make_pairs(2).into_iter().collect();
643+
assert_eq!(inline.storage_variant_for_memory_diagnostics(), "Inline");
644+
let frozen = inline.clone().freeze();
645+
646+
let mut btree: Object = make_pairs(3).into_iter().collect();
647+
btree.remove(&val(2));
648+
assert_eq!(btree.storage_variant_for_memory_diagnostics(), "BTree");
649+
650+
assert_eq!(inline, frozen);
651+
assert_eq!(inline, btree);
652+
}
653+
654+
#[test]
655+
fn object_cursor_frozen_one_entry_yields_once() {
656+
let obj = Object::from_iter([(val(1), val(2))]).freeze();
657+
let mut cursor = obj.cursor();
658+
assert_eq!(obj.next(&mut cursor), Some((&val(1), &val(2))));
659+
assert!(obj.next(&mut cursor).is_none());
660+
}
661+
662+
#[test]
663+
fn object_iter_mut_on_frozen_persists_changes() {
664+
let mut obj = Object::from_iter([(val(1), val(2))]).freeze();
665+
for (_, value) in obj.iter_mut() {
666+
*value = val(3);
667+
}
668+
assert_eq!(obj.get(&val(1)), Some(&val(3)));
669+
}
670+
671+
#[test]
672+
fn value_freeze_recursive_freezes_nested_objects() {
673+
let mut inner = Object::new();
674+
inner.insert(val(1), val(2));
675+
676+
let mut set = alloc::collections::BTreeSet::new();
677+
set.insert(inner.clone().into_value());
678+
679+
let mut outer = Object::new();
680+
outer.insert(
681+
Value::from("array"),
682+
Value::from(Vec::from([inner.into_value()])),
683+
);
684+
outer.insert(Value::from("set"), Value::from(set));
685+
686+
let mut value = outer.into_value();
687+
value.freeze_recursive();
688+
assert_all_objects_frozen(&value);
689+
}
690+
691+
#[test]
692+
fn object_hybrid_insert_existing_on_frozen_stays_frozen() {
693+
let mut obj = Object::from_iter([(val(1), val(2))]).freeze();
694+
assert_eq!(obj.storage_variant_for_memory_diagnostics(), "Frozen");
695+
assert_eq!(obj.insert(val(1), val(9)), Some(val(2)));
696+
assert_eq!(obj.storage_variant_for_memory_diagnostics(), "Frozen");
697+
assert_eq!(obj.get(&val(1)), Some(&val(9)));
698+
}

0 commit comments

Comments
 (0)