43
Testing
Tests live next to the code in #[cfg(test)] mod tests. We exercise basic ops, iteration in both directions, clone, equality, and a stress loop. Then we run the same tests under Miri, which interprets the program and flags every undefined-behavior trigger we managed to write past the type system.
- A handful of unit tests: round-trip push/pop on each end, drain via iteration, mutate through
IterMut, clone-equals-original. Together these touch every method at least once and walk both directions.#[cfg(test)] mod tests { use super::*; #[test] fn push_pop_front() { let mut l = LinkedList::new(); l.push_front(1); l.push_front(2); assert_eq!(l.pop_front(), Some(2)); assert_eq!(l.pop_front(), Some(1)); assert_eq!(l.pop_front(), None); } #[test] fn iter_mut_doubles() { let mut l: LinkedList<i32> = (1..=4).collect(); for x in l.iter_mut() { *x *= 2; } assert!(l.iter().copied().eq([2, 4, 6, 8])); } #[test] fn clone_eq() { let a: LinkedList<String> = (0..50).map(|i| i.to_string()).collect(); let b = a.clone(); assert_eq!(a, b); } } - Run the unit tests under Miri:
cargo +nightly miri test. Miri interprets every operation and validates against the stacked-borrows / tree-borrows model. Any aliasing or provenance violation we wrote earns a stack trace.$ rustup toolchain install nightly $ rustup +nightly component add miri $ cargo +nightly miri test Compiling sixth v0.1.0 Running unittests src/lib.rs running 3 tests test sixth::tests::push_pop_front ... ok test sixth::tests::iter_mut_doubles ... ok test sixth::tests::clone_eq ... ok test result: ok. 3 passed; 0 failed