use super::*;
#[test]
fn intern_dedup() {
crate::test_utils::init_test_tracing();
let mut interner = StringInterner::new();
let a = interner.intern("foo");
let b = interner.intern("foo");
let c = interner.intern("bar");
assert_eq!(a, b);
assert_ne!(a, c);
assert_eq!(interner.resolve(a), "foo");
assert_eq!(interner.resolve(c), "bar");
}
#[test]
fn runtime_intern() {
crate::test_utils::init_test_tracing();
let a = intern("hello");
let b = intern("hello");
let c = intern("world");
assert_eq!(a, b);
assert_ne!(a, c);
assert_eq!(resolve_sym(a), "hello");
assert_eq!(resolve_sym(c), "world");
}
#[test]
fn intern_empty_string() {
crate::test_utils::init_test_tracing();
let mut interner = StringInterner::new();
let id = interner.intern("");
assert_eq!(interner.resolve(id), "");
assert_eq!(interner.intern(""), id);
}
#[test]
fn intern_many_strings() {
crate::test_utils::init_test_tracing();
let mut interner = StringInterner::new();
let ids: Vec<SymId> = (0..1000)
.map(|i| interner.intern(&format!("sym-{i}")))
.collect();
for (i, id) in ids.iter().enumerate() {
assert_eq!(interner.resolve(*id), format!("sym-{i}"));
}
let unique: std::collections::HashSet<SymId> = ids.iter().copied().collect();
assert_eq!(unique.len(), 1000);
}
#[test]
fn intern_idempotent() {
crate::test_utils::init_test_tracing();
let mut interner = StringInterner::new();
let first = interner.intern("repeated");
for _ in 0..100 {
assert_eq!(interner.intern("repeated"), first);
}
}
#[test]
fn symid_copy_eq_hash() {
crate::test_utils::init_test_tracing();
let mut interner = StringInterner::new();
let a = interner.intern("x");
let b = a; assert_eq!(a, b);
use std::collections::HashSet;
let mut set = HashSet::new();
set.insert(a);
assert!(set.contains(&b));
}
#[test]
fn resolve_sym_stable_across_growth() {
crate::test_utils::init_test_tracing();
let mut interner = StringInterner::new();
let early = interner.intern("early");
assert_eq!(interner.resolve(early), "early");
for i in 0..500 {
interner.intern(&format!("growth-{i}"));
}
assert_eq!(interner.resolve(early), "early");
}
#[test]
fn canonical_id_distinguishes_interned_from_uninterned_duplicates() {
crate::test_utils::init_test_tracing();
let mut interner = StringInterner::new();
let canonical = interner.intern("dup");
let uninterned = interner.intern_uninterned("dup");
assert!(interner.is_canonical_id(canonical));
assert!(!interner.is_canonical_id(uninterned));
assert_eq!(interner.lookup("dup"), Some(canonical));
}
#[test]
fn canonical_id_survives_dump_style_reconstruction() {
crate::test_utils::init_test_tracing();
let interner = StringInterner::from_strings(vec![
"nil".to_owned(),
"t".to_owned(),
"dup".to_owned(),
"dup".to_owned(),
]);
assert!(interner.is_canonical_id(SymId(2)));
assert!(!interner.is_canonical_id(SymId(3)));
assert_eq!(interner.lookup("dup"), Some(SymId(2)));
}