Skip to content

Commit 19c0585

Browse files
authored
Add treap BST and heap property tests, and stress tests (#16)
- test_bst_property: verifies in-order traversal yields sorted keys - test_heap_property: verifies parent priority >= child priorities - Adds helper functions for property verification
1 parent 10080ac commit 19c0585

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed

src/treap.rs

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,34 @@ mod tests {
271271
use rand::SeedableRng;
272272
use rand::rngs::StdRng;
273273

274+
// Helper: collect keys via in-order traversal (should yield sorted order for valid BST)
275+
fn collect_inorder<T: Ord + Clone>(node: &Option<Box<Node<T>>>) -> Vec<T> {
276+
match node {
277+
None => vec![],
278+
Some(n) => {
279+
let mut result = collect_inorder(&n.left);
280+
result.push(n.key.clone());
281+
result.extend(collect_inorder(&n.right));
282+
result
283+
}
284+
}
285+
}
286+
287+
// Helper: verify max-heap property (parent priority >= child priorities)
288+
fn verify_heap_property<T: Ord>(node: &Option<Box<Node<T>>>) -> bool {
289+
match node {
290+
None => true,
291+
Some(n) => {
292+
let left_ok = n.left.as_ref().is_none_or(|l| n.priority >= l.priority);
293+
let right_ok = n.right.as_ref().is_none_or(|r| n.priority >= r.priority);
294+
left_ok
295+
&& right_ok
296+
&& verify_heap_property(&n.left)
297+
&& verify_heap_property(&n.right)
298+
}
299+
}
300+
}
301+
274302
#[test]
275303
fn test_insert_and_contains() {
276304
let mut treap = Treap::new();
@@ -352,4 +380,168 @@ mod tests {
352380
assert!(treap.insert(5, &mut rng)); // Re-insertion returns true
353381
assert_eq!(treap.len(), 3);
354382
}
383+
384+
#[test]
385+
fn test_bst_property() {
386+
let mut treap = Treap::new();
387+
let mut rng = StdRng::seed_from_u64(123);
388+
389+
// Insert elements in random order
390+
let elements = vec![50, 25, 75, 10, 30, 60, 90, 5, 15, 27, 35];
391+
for elem in &elements {
392+
treap.insert(*elem, &mut rng);
393+
}
394+
395+
// In-order traversal should yield sorted keys
396+
let inorder = collect_inorder(&treap.root);
397+
let mut sorted = elements.clone();
398+
sorted.sort();
399+
assert_eq!(inorder, sorted);
400+
401+
// Test after some removals
402+
treap.remove(&25);
403+
treap.remove(&75);
404+
let inorder_after = collect_inorder(&treap.root);
405+
let expected: Vec<i32> = sorted.into_iter().filter(|&x| x != 25 && x != 75).collect();
406+
assert_eq!(inorder_after, expected);
407+
}
408+
409+
#[test]
410+
fn test_heap_property() {
411+
let mut treap = Treap::new();
412+
let mut rng = StdRng::seed_from_u64(456);
413+
414+
// Insert many elements
415+
for i in 0..100 {
416+
treap.insert(i, &mut rng);
417+
assert!(
418+
verify_heap_property(&treap.root),
419+
"Heap property violated after inserting {}",
420+
i
421+
);
422+
}
423+
424+
// Test after removals
425+
for i in (0..100).step_by(3) {
426+
treap.remove(&i);
427+
assert!(
428+
verify_heap_property(&treap.root),
429+
"Heap property violated after removing {}",
430+
i
431+
);
432+
}
433+
434+
// Test after retain
435+
treap.retain(|&x| x % 2 == 0);
436+
assert!(
437+
verify_heap_property(&treap.root),
438+
"Heap property violated after retain"
439+
);
440+
}
441+
442+
#[test]
443+
fn test_stress_insert_remove() {
444+
let mut treap = Treap::new();
445+
let mut rng = StdRng::seed_from_u64(789);
446+
447+
// Insert 1000 elements
448+
for i in 0..1000 {
449+
treap.insert(i, &mut rng);
450+
}
451+
assert_eq!(treap.len(), 1000);
452+
453+
// Verify all elements present
454+
for i in 0..1000 {
455+
assert!(treap.contains(&i), "Element {} should be present", i);
456+
}
457+
458+
// Remove every other element
459+
for i in (0..1000).step_by(2) {
460+
assert!(treap.remove(&i), "Should remove {}", i);
461+
}
462+
assert_eq!(treap.len(), 500);
463+
464+
// Verify correct elements remain
465+
for i in 0..1000 {
466+
if i % 2 == 0 {
467+
assert!(!treap.contains(&i), "Element {} should be removed", i);
468+
} else {
469+
assert!(treap.contains(&i), "Element {} should remain", i);
470+
}
471+
}
472+
473+
// Re-insert removed elements
474+
for i in (0..1000).step_by(2) {
475+
assert!(treap.insert(i, &mut rng), "Should insert {}", i);
476+
}
477+
assert_eq!(treap.len(), 1000);
478+
479+
// Verify invariants
480+
let inorder = collect_inorder(&treap.root);
481+
let expected: Vec<i32> = (0..1000).collect();
482+
assert_eq!(inorder, expected);
483+
assert!(verify_heap_property(&treap.root));
484+
}
485+
486+
#[test]
487+
fn test_empty_tree_operations() {
488+
let mut treap: Treap<i32> = Treap::new();
489+
let mut rng = StdRng::seed_from_u64(999);
490+
491+
// Operations on empty treap
492+
assert!(treap.is_empty());
493+
assert_eq!(treap.len(), 0);
494+
assert!(!treap.contains(&42));
495+
assert!(!treap.remove(&42));
496+
497+
// Retain on empty treap (should be no-op)
498+
treap.retain(|_| true);
499+
assert!(treap.is_empty());
500+
501+
// Clear on empty treap
502+
treap.clear();
503+
assert!(treap.is_empty());
504+
505+
// Insert then clear
506+
treap.insert(1, &mut rng);
507+
treap.insert(2, &mut rng);
508+
assert_eq!(treap.len(), 2);
509+
treap.clear();
510+
assert!(treap.is_empty());
511+
assert!(!treap.contains(&1));
512+
assert!(!treap.contains(&2));
513+
}
514+
515+
#[test]
516+
fn test_single_element() {
517+
let mut treap = Treap::new();
518+
let mut rng = StdRng::seed_from_u64(111);
519+
520+
// Single element operations
521+
treap.insert(42, &mut rng);
522+
assert_eq!(treap.len(), 1);
523+
assert!(treap.contains(&42));
524+
assert!(!treap.contains(&0));
525+
526+
// Duplicate of single element
527+
assert!(!treap.insert(42, &mut rng));
528+
assert_eq!(treap.len(), 1);
529+
530+
// Remove single element
531+
assert!(treap.remove(&42));
532+
assert!(treap.is_empty());
533+
assert!(!treap.contains(&42));
534+
535+
// Re-insert
536+
treap.insert(42, &mut rng);
537+
assert_eq!(treap.len(), 1);
538+
539+
// Retain that keeps the element
540+
treap.retain(|&x| x == 42);
541+
assert_eq!(treap.len(), 1);
542+
543+
// Retain that removes the element
544+
treap.retain(|&x| x != 42);
545+
assert!(treap.is_empty());
546+
}
355547
}

0 commit comments

Comments
 (0)