use super::*;
use crate::succinct::RankSelectInterleaved256;
#[test]
fn test_unified_trie_creation() {
let trie: ZiporaTrie = ZiporaTrie::new();
assert_eq!(trie.len(), 0);
assert!(trie.is_empty());
}
#[test]
fn test_cache_optimized_config() {
let trie: ZiporaTrie = ZiporaTrie::with_config(ZiporaTrieConfig::cache_optimized());
assert!(trie.is_cache_optimized());
}
#[test]
fn test_space_optimized_config() {
let trie: ZiporaTrie = ZiporaTrie::with_config(ZiporaTrieConfig::space_optimized());
assert_eq!(trie.len(), 0);
}
#[test]
fn test_string_specialized_config() {
let trie: ZiporaTrie = ZiporaTrie::with_config(ZiporaTrieConfig::string_specialized());
assert_eq!(trie.len(), 0);
}
#[test]
fn test_double_array_insert_contains() {
let mut trie: ZiporaTrie = ZiporaTrie::new();
trie.insert(b"hello").unwrap();
assert_eq!(trie.len(), 1);
assert!(trie.contains(b"hello"));
assert!(!trie.contains(b"world"));
trie.insert(b"world").unwrap();
assert_eq!(trie.len(), 2);
assert!(trie.contains(b"hello"));
assert!(trie.contains(b"world"));
trie.insert(b"help").unwrap();
assert_eq!(trie.len(), 3);
assert!(trie.contains(b"help"));
assert!(trie.contains(b"hello"));
trie.insert(b"hello").unwrap();
assert_eq!(trie.len(), 3);
}
#[test]
fn test_double_array_keys() {
let mut trie: ZiporaTrie = ZiporaTrie::new();
trie.insert(b"apple").unwrap();
trie.insert(b"app").unwrap();
trie.insert(b"banana").unwrap();
let mut keys = trie.keys();
keys.sort();
assert_eq!(keys.len(), 3);
assert_eq!(keys[0], b"app");
assert_eq!(keys[1], b"apple");
assert_eq!(keys[2], b"banana");
}
#[test]
fn test_double_array_prefix_with_empty_key() {
let mut trie: ZiporaTrie = ZiporaTrie::new();
trie.insert(b"").unwrap();
trie.insert(b"a").unwrap();
trie.insert(b"ab").unwrap();
trie.insert(b"abc").unwrap();
trie.insert(b"abd").unwrap();
trie.insert(b"b").unwrap();
let all = trie.keys_with_prefix(b"");
assert_eq!(
all.len(),
6,
"keys_with_prefix('') should return all 6 keys"
);
}
#[test]
fn test_double_array_empty_key() {
let mut trie: ZiporaTrie = ZiporaTrie::new();
trie.insert(b"").unwrap();
trie.insert(b"a").unwrap();
trie.insert(b"ab").unwrap();
assert_eq!(trie.len(), 3);
assert!(trie.contains(b""));
assert!(trie.contains(b"a"));
assert!(trie.contains(b"ab"));
let mut keys = trie.keys();
keys.sort();
assert_eq!(keys.len(), 3, "Should have 3 keys including empty");
assert_eq!(keys[0], b"");
assert_eq!(keys[1], b"a");
assert_eq!(keys[2], b"ab");
}
#[test]
fn test_lazy_stats() {
let mut trie: ZiporaTrie = ZiporaTrie::new();
for i in 0..100 {
trie.insert(format!("key{:03}", i).as_bytes()).unwrap();
}
assert_eq!(trie.len(), 100);
let stats = trie.stats();
assert_eq!(stats.num_keys, 100);
assert!(stats.memory_usage > 0);
assert!(stats.num_states > 0);
}
#[test]
fn test_no_double_traversal_duplicate() {
let mut trie: ZiporaTrie = ZiporaTrie::new();
trie.insert(b"abc").unwrap();
trie.insert(b"abc").unwrap();
trie.insert(b"abc").unwrap();
assert_eq!(trie.len(), 1);
trie.insert(b"def").unwrap();
trie.insert(b"def").unwrap();
assert_eq!(trie.len(), 2);
}
#[test]
fn test_patricia_compact_node() {
let config = ZiporaTrieConfig {
trie_strategy: crate::fsa::TrieStrategy::Patricia {
max_path_length: 64,
compression_threshold: 4,
adaptive_compression: true,
},
..ZiporaTrieConfig::default()
};
let mut trie: ZiporaTrie = ZiporaTrie::with_config(config);
trie.insert(b"hello").unwrap();
trie.insert(b"help").unwrap();
trie.insert(b"world").unwrap();
assert_eq!(trie.len(), 3);
assert!(trie.contains(b"hello"));
assert!(trie.contains(b"help"));
assert!(trie.contains(b"world"));
assert!(!trie.contains(b"hel"));
}
#[test]
fn test_find_free_base_many_inserts() {
let mut trie: ZiporaTrie = ZiporaTrie::new();
for i in 0..500 {
trie.insert(format!("key_{:04}", i).as_bytes()).unwrap();
}
assert_eq!(trie.len(), 500);
assert!(trie.contains(b"key_0000"));
assert!(trie.contains(b"key_0250"));
assert!(trie.contains(b"key_0499"));
assert!(!trie.contains(b"key_0500"));
}
#[test]
fn test_amortized_growth() {
let mut trie: ZiporaTrie = ZiporaTrie::new();
for i in 0..1000 {
trie.insert(format!("{:04}", i).as_bytes()).unwrap();
}
assert_eq!(trie.len(), 1000);
}
#[test]
fn test_trie_map() {
let mut map = ZiporaTrieMap::<u32, RankSelectInterleaved256>::new();
map.insert(b"hello", 42).unwrap();
map.insert(b"world", 100).unwrap();
map.insert(b"help", 7).unwrap();
assert_eq!(map.get(b"hello"), Some(42));
assert_eq!(map.get(b"world"), Some(100));
assert_eq!(map.get(b"help"), Some(7));
assert_eq!(map.get(b"missing"), None);
assert_eq!(map.len(), 3);
let prev = map.insert(b"hello", 99).unwrap();
assert_eq!(prev, Some(42));
assert_eq!(map.get(b"hello"), Some(99));
assert_eq!(map.len(), 3); }
#[test]
fn test_build_from_sorted() {
let keys: Vec<&[u8]> = vec![b"apple", b"application", b"apply", b"banana", b"band"];
let trie: ZiporaTrie =
ZiporaTrie::build_from_sorted(&keys, ZiporaTrieConfig::default()).unwrap();
assert_eq!(trie.len(), 5);
assert!(trie.contains(b"apple"));
assert!(trie.contains(b"application"));
assert!(trie.contains(b"apply"));
assert!(trie.contains(b"banana"));
assert!(trie.contains(b"band"));
assert!(!trie.contains(b"ban"));
}
#[test]
fn test_default_is_double_array() {
let config = ZiporaTrieConfig::default();
assert!(matches!(
config.trie_strategy,
crate::fsa::TrieStrategy::DoubleArray { .. }
));
}
#[test]
fn test_double_array_remove() {
let mut trie: ZiporaTrie = ZiporaTrie::new();
trie.insert(b"hello").unwrap();
trie.insert(b"world").unwrap();
assert_eq!(trie.len(), 2);
assert!(trie.remove(b"hello").unwrap());
assert_eq!(trie.len(), 1);
assert!(!trie.contains(b"hello"));
assert!(trie.contains(b"world"));
assert!(!trie.remove(b"missing").unwrap());
assert_eq!(trie.len(), 1);
}
#[test]
fn test_double_array_node_id_roundtrip() {
let mut trie: ZiporaTrie = ZiporaTrie::new();
trie.insert(b"hello").unwrap();
trie.insert(b"world").unwrap();
let node_id = trie.lookup_node_id(b"hello").expect("should find hello");
let restored = trie.restore_string(node_id).expect("should restore");
assert_eq!(restored, b"hello");
let node_id2 = trie.lookup_node_id(b"world").expect("should find world");
let restored2 = trie.restore_string(node_id2).expect("should restore");
assert_eq!(restored2, b"world");
assert!(trie.lookup_node_id(b"missing").is_none());
}