From 814e2bbc48c3678754aaadb3b99d9256b146fdf3 Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Mon, 26 May 2025 13:57:17 +0300 Subject: [PATCH 1/5] Write more granular tests --- src/lib.rs | 421 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 272 insertions(+), 149 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0cd667c..09dc921 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -778,9 +778,13 @@ mod tests { fn assert_is_core_error() {} #[test] - fn construct() { - assert!(Vec::::new().is_empty()); - assert!(Vec::::default().is_empty()); + fn new() { + let vec = Vec::::new(); + assert!(vec.is_empty()); + assert!(!vec.is_full()); + assert_eq!(vec.len(), 0); + assert_eq!(vec.capacity(), 10); + assert_eq!(DEFAULTS.get(), 0); } #[test] @@ -789,6 +793,16 @@ mod tests { let _ = Vec::::new(); } + #[test] + fn default() { + let vec = Vec::::default(); + assert!(vec.is_empty()); + assert!(!vec.is_full()); + assert_eq!(vec.len(), 0); + assert_eq!(vec.capacity(), 10); + assert_eq!(DEFAULTS.get(), 0); + } + #[test] #[should_panic(expected = "CAPACITY must be greater than 0")] fn default_with_capacity_zero() { @@ -808,6 +822,54 @@ mod tests { assert_eq!(vec.capacity(), 3); } + #[test] + fn len() { + let mut vec = Vec::::new(); + + assert_eq!(vec.len(), 0); + + vec.set_len(2).unwrap(); + assert_eq!(vec.len(), 2); + + vec.push(1).unwrap(); + assert_eq!(vec.len(), 3); + + vec.clear(); + assert_eq!(vec.len(), 0); + } + + #[test] + fn is_empty() { + let mut vec = Vec::::new(); + + assert!(vec.is_empty()); + + vec.push(1).unwrap(); + assert!(!vec.is_empty()); + + vec.set_len(2).unwrap(); + assert!(!vec.is_empty()); + + vec.clear(); + assert!(vec.is_empty()); + } + + #[test] + fn is_full() { + let mut vec = Vec::::new(); + + assert!(!vec.is_full()); + + vec.push(1).unwrap(); + assert!(!vec.is_full()); + + vec.set_len(3).unwrap(); + assert!(vec.is_full()); + + vec.clear(); + assert!(!vec.is_full()); + } + #[test] fn push() { let mut vec = Vec::::new(); @@ -818,94 +880,253 @@ mod tests { assert_eq!(format!("{}", vec.push(3).unwrap_err()), "vector needs larger capacity"); assert_is_core_error::(); - assert_eq!(vec.get(0).unwrap(), &1); - assert_eq!(vec.get(1).unwrap(), &2); + assert_eq!(vec.as_slice(), &[1, 2]); assert!(vec.get(2).is_none()); + assert!(vec.get(99).is_none()); + } + + #[test] + fn push_should_not_create_default_elements() { + let mut vec = Vec::::new(); + vec.push(Struct { i: 0 }).unwrap(); + assert_eq!(DEFAULTS.get(), 0); + } + + #[test] + fn push_should_not_clone_element() { + let mut vec = Vec::::new(); + + vec.push(Struct { i: 0 }).unwrap(); + assert_eq!(CLONES.get(), 0); + + vec.push(Struct { i: 0 }).unwrap(); + vec.push(Struct { i: 0 }).unwrap(); + assert_eq!(CLONES.get(), 0); } #[test] - fn size() { + fn clear() { let mut vec = Vec::::new(); + + vec.extend_from_slice(&[1, 2, 3]).unwrap(); + assert_eq!(vec.len(), 3); + assert_eq!(vec.capacity(), 3); + assert!(!vec.is_empty()); + assert!(vec.is_full()); + + vec.clear(); + assert_eq!(vec.len(), 0); + assert_eq!(vec.capacity(), 3); assert!(vec.is_empty()); assert!(!vec.is_full()); + } - vec.push(1).unwrap(); - vec.push(2).unwrap(); - assert_eq!(vec.len(), 2); - assert!(!vec.is_empty()); - assert!(!vec.is_full()); + #[test] + fn clear_should_drop_all_allocated_elements() { + let mut vec = Vec::::new(); + assert_eq!(DROPS.get(), 0); + + let s = Struct { i: 0 }; + for _ in 1..=3 { + vec.push(s.clone()).unwrap(); + } + assert_eq!(DROPS.get(), 0); + + vec.clear(); + assert_eq!(DROPS.get(), 3); + + assert_eq!(CLONES.get(), 3); // the three clones before push + assert_eq!(DEFAULTS.get(), 0); + } + + #[test] + fn set_len() { + let mut vec = Vec::::new(); assert!(vec.set_len(1).is_ok()); assert_eq!(vec.len(), 1); assert!(!vec.is_empty()); assert!(!vec.is_full()); + assert_eq!(vec.as_slice(), [0]); assert!(matches!(vec.set_len(100), Err(CapacityError))); assert_eq!(format!("{}", vec.set_len(100).unwrap_err()), "vector needs larger capacity"); assert_is_core_error::(); + assert_eq!(vec.len(), 1); + assert!(!vec.is_empty()); assert!(!vec.is_full()); + assert_eq!(vec.as_slice(), [0]); vec.clear(); - assert!(!vec.is_full()); + vec.set_len(vec.capacity()).unwrap(); + assert_eq!(vec.len(), 3); + assert!(!vec.is_empty()); + assert!(vec.is_full()); + assert_eq!(vec.as_slice(), [0, 0, 0]); + + assert!(vec.set_len(0).is_ok()); assert_eq!(vec.len(), 0); assert!(vec.is_empty()); + assert!(!vec.is_full()); + assert_eq!(vec.as_slice(), []); + } - vec.set_len(vec.capacity()).unwrap(); - assert!(vec.is_full()); + #[test] + fn set_len_should_create_default_elements() { + let mut vec = Vec::::new(); + + // Length zero, no defaults + vec.set_len(0).unwrap(); + assert_eq!(DEFAULTS.get(), 0); + + // Length error, no defaults + vec.set_len(99).unwrap_err(); + assert_eq!(DEFAULTS.get(), 0); + + // Maximum length, create `CAPACITY` default values + vec.set_len(10).unwrap(); + assert_eq!(DEFAULTS.get(), 10); + + // Smaller length than current, no defaults + DEFAULTS.set(0); + vec.set_len(5).unwrap(); + assert_eq!(DEFAULTS.get(), 0); + + // Larger length than current, create `current length - new length` default values + DEFAULTS.set(0); + vec.set_len(8).unwrap(); + assert_eq!(DEFAULTS.get(), 3); + } + + #[test] + fn set_len_should_drop_all_allocated_elements() { + let mut vec = Vec::::new(); + assert_eq!(DROPS.get(), 0); + + let s = Struct { i: 0 }; + for _ in 1..=5 { + vec.push(s.clone()).unwrap(); + } + assert_eq!(DROPS.get(), 0); + + // Same length, no drops + vec.set_len(5).unwrap(); + assert_eq!(DROPS.get(), 0); + + // Length error, no drop + vec.set_len(999).unwrap_err(); + assert_eq!(DROPS.get(), 0); + + // Length smaller, drop elements after + vec.set_len(2).unwrap(); + assert_eq!(DROPS.get(), 3); + + // Same length again, no change in number of drops + vec.set_len(2).unwrap(); + assert_eq!(DROPS.get(), 3); + + // Length zero, drop all + DROPS.set(0); + vec.set_len(0).unwrap(); + assert_eq!(DROPS.get(), 2); + + assert_eq!(CLONES.get(), 5); // the five clones before push + assert_eq!(DEFAULTS.get(), 0); } #[test] - fn get_immutable() { + fn first() { let mut vec = Vec::::new(); assert!(vec.first().is_none()); - assert!(vec.last().is_none()); - assert!(vec.get(0).is_none()); vec.push(1).unwrap(); assert_eq!(vec.first().unwrap(), &1); - assert_eq!(vec.get(0).unwrap(), &1); - assert_eq!(vec.last().unwrap(), &1); vec.push(2).unwrap(); vec.push(3).unwrap(); assert_eq!(vec.first().unwrap(), &1); - assert_eq!(vec.last().unwrap(), &3); - assert_eq!(vec.get(0).unwrap(), &1); - assert_eq!(vec.get(1).unwrap(), &2); - assert_eq!(vec.get(2).unwrap(), &3); - assert!(vec.get(3).is_none()); } #[test] - fn get_mutable() { + fn first_mut() { let mut vec = Vec::::new(); assert!(vec.first_mut().is_none()); - assert!(vec.last_mut().is_none()); - assert!(vec.get_mut(0).is_none()); vec.push(1).unwrap(); assert_eq!(vec.first_mut().unwrap(), &1); - assert_eq!(vec.get_mut(0).unwrap(), &1); - assert_eq!(vec.last_mut().unwrap(), &1); vec.push(2).unwrap(); vec.push(3).unwrap(); assert_eq!(vec.first_mut().unwrap(), &1); - assert_eq!(vec.last_mut().unwrap(), &3); - assert_eq!(vec.get_mut(0).unwrap(), &1); - assert_eq!(vec.get_mut(1).unwrap(), &2); - assert_eq!(vec.get_mut(2).unwrap(), &3); - assert!(vec.get_mut(3).is_none()); - *vec.get_mut(0).unwrap() = 5; - assert_eq!(vec.get_mut(0).unwrap(), &5); + *vec.first_mut().unwrap() = 4; + assert_eq!(vec.as_slice(), [4, 2, 3]); + } + + #[test] + fn last() { + let mut vec = Vec::::new(); + assert!(vec.last().is_none()); + + vec.push(1).unwrap(); + assert_eq!(vec.last().unwrap(), &1); + + vec.push(2).unwrap(); + assert_eq!(vec.last().unwrap(), &2); + + vec.push(3).unwrap_err(); + assert_eq!(vec.last(), Some(&2)); + } + + #[test] + fn last_mut() { + let mut vec = Vec::::new(); + assert!(vec.last_mut().is_none()); + + vec.push(1).unwrap(); + assert_eq!(vec.last_mut().unwrap(), &1); + + vec.push(2).unwrap(); + assert_eq!(vec.last_mut().unwrap(), &2); + + vec.push(3).unwrap_err(); + assert_eq!(vec.last_mut().unwrap(), &2); - *vec.first_mut().unwrap() = 15; - assert_eq!(vec.first_mut().unwrap(), &15); + *vec.last_mut().unwrap() = 4; + assert_eq!(vec.as_slice(), [1, 4]); - *vec.last_mut().unwrap() = 25; - assert_eq!(vec.last_mut().unwrap(), &25); + vec.set_len(1).unwrap(); + assert_eq!(vec.last_mut(), Some(&mut 1)); + } + + #[test] + fn get() { + let mut vec = Vec::::new(); + assert!(vec.get(0).is_none()); + + vec.push(1).unwrap(); + assert_eq!(vec.get(0), Some(&1)); + + vec.push(2).unwrap(); + assert_eq!(vec.get(1), Some(&2)); + + assert_eq!(vec.get(3), None); + } + + #[test] + fn get_mut() { + let mut vec = Vec::::new(); + assert!(vec.get_mut(0).is_none()); + + vec.push(1).unwrap(); + assert_eq!(vec.get_mut(0), Some(&mut 1)); + + vec.push(2).unwrap(); + *vec.get_mut(1).unwrap() = 3; + assert_eq!(vec.get_mut(1), Some(&mut 3)); + + assert_eq!(vec.get_mut(3), None); } #[test] @@ -1045,13 +1266,19 @@ mod tests { #[test] fn as_slice() { let mut vec = Vec::::new(); + assert_eq!(vec.as_slice(), []); + + vec.extend_from_slice(&[1, 2, 3]).unwrap(); + assert_eq!(vec.as_slice(), [1, 2, 3]); + } - assert_eq!(vec.as_mut_slice().iter().sum::(), 0); - assert_eq!(vec.as_slice().iter().sum::(), 0); + #[test] + fn as_mut_slice() { + let mut vec = Vec::::new(); + assert_eq!(vec.as_mut_slice(), []); - vec.push(10).unwrap(); - assert_eq!(vec.as_mut_slice().iter().sum::(), 10); - assert_eq!(vec.as_slice().iter().sum::(), 10); + vec.extend_from_slice(&[1, 2, 3]).unwrap(); + assert_eq!(vec.as_mut_slice(), [1, 2, 3]); vec.set_len(1000).unwrap(); vec.as_mut_slice().fill(2); @@ -1158,110 +1385,6 @@ mod tests { assert_eq!(new.as_slice(), elements); } - #[test] - fn construct_should_not_create_default_elements() { - let _ = Vec::::new(); - assert_eq!(DEFAULTS.get(), 0); - } - - #[test] - fn push_should_not_create_default_elements() { - let mut vec = Vec::::new(); - vec.push(Struct { i: 0 }).unwrap(); - assert_eq!(DEFAULTS.get(), 0); - } - - #[test] - fn set_len_should_create_default_elements() { - let mut vec = Vec::::new(); - - // Length zero, no defaults - vec.set_len(0).unwrap(); - assert_eq!(DEFAULTS.get(), 0); - - // Length error, no defaults - vec.set_len(99).unwrap_err(); - assert_eq!(DEFAULTS.get(), 0); - - // Maximum length, create `CAPACITY` default values - vec.set_len(10).unwrap(); - assert_eq!(DEFAULTS.get(), 10); - - // Smaller length than current, no defaults - DEFAULTS.set(0); - vec.set_len(5).unwrap(); - assert_eq!(DEFAULTS.get(), 0); - - // Larger length than current, create `current length - new length` default values - DEFAULTS.set(0); - vec.set_len(8).unwrap(); - assert_eq!(DEFAULTS.get(), 3); - } - - #[test] - fn push_should_not_clone_element() { - let mut vec = Vec::::new(); - - vec.push(Struct { i: 0 }).unwrap(); - assert_eq!(CLONES.get(), 0); - - vec.push(Struct { i: 0 }).unwrap(); - vec.push(Struct { i: 0 }).unwrap(); - assert_eq!(CLONES.get(), 0); - } - - #[test] - fn clear_should_drop_all_allocated_elements() { - let mut vec = Vec::::new(); - assert_eq!(DROPS.get(), 0); - - let s = Struct { i: 0 }; - for _ in 1..=3 { - vec.push(s.clone()).unwrap(); - } - assert_eq!(DROPS.get(), 0); - - vec.clear(); - assert_eq!(DROPS.get(), 3); - - assert_eq!(CLONES.get(), 3); // the three clones before push - } - - #[test] - fn set_len_should_drop_all_allocated_elements() { - let mut vec = Vec::::new(); - assert_eq!(DROPS.get(), 0); - - let s = Struct { i: 0 }; - for _ in 1..=5 { - vec.push(s.clone()).unwrap(); - } - assert_eq!(DROPS.get(), 0); - - // Same length, no drops - vec.set_len(5).unwrap(); - assert_eq!(DROPS.get(), 0); - - // Length error, no drop - vec.set_len(999).unwrap_err(); - assert_eq!(DROPS.get(), 0); - - // Length smaller, drop elements after - vec.set_len(2).unwrap(); - assert_eq!(DROPS.get(), 3); - - // Same length again, no change in number of drops - vec.set_len(2).unwrap(); - assert_eq!(DROPS.get(), 3); - - // Length zero, drop all - DROPS.set(0); - vec.set_len(0).unwrap(); - assert_eq!(DROPS.get(), 2); - - assert_eq!(CLONES.get(), 5); // the five clones before push - } - #[test] fn going_out_of_scope_should_drop_all_allocated_elements() { let s = Struct { i: 0 }; From f75fc5dfd0bc86fc9435226db9197432aa9a8f31 Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Mon, 26 May 2025 14:01:58 +0300 Subject: [PATCH 2/5] Checkout branch --- .github/doc/doc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/doc/doc.py b/.github/doc/doc.py index a12cd52..6e3036f 100755 --- a/.github/doc/doc.py +++ b/.github/doc/doc.py @@ -39,7 +39,7 @@ def copy_existing_versions(gh_pages: Path, docs: Path): def generate_docs(build: Path, docs: Path, git_ref: str, redirect_template: Path): """Generate documentation for the given Git reference.""" print(f"Generating docs for {git_ref}...") - run_cmd(f"git checkout {git_ref}") + run_cmd(f"git checkout {git_ref} --") run_cmd(f"cargo doc --no-deps --target-dir={build}") (docs / git_ref).mkdir(parents=True, exist_ok=True) From a02b6cf81fbde17d0fb07f990450643e329898ae Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Mon, 26 May 2025 15:32:05 +0300 Subject: [PATCH 3/5] Test get with index capacity --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 09dc921..fe1718a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1111,6 +1111,7 @@ mod tests { vec.push(2).unwrap(); assert_eq!(vec.get(1), Some(&2)); + assert_eq!(vec.get(2), None); assert_eq!(vec.get(3), None); } @@ -1126,6 +1127,7 @@ mod tests { *vec.get_mut(1).unwrap() = 3; assert_eq!(vec.get_mut(1), Some(&mut 3)); + assert_eq!(vec.get_mut(2), None); assert_eq!(vec.get_mut(3), None); } From b5eb7d0cbe014fda2ba2ad87c75f166ed4f6fbea Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Mon, 26 May 2025 15:50:00 +0300 Subject: [PATCH 4/5] Verify more elements --- src/lib.rs | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fe1718a..a7efc3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -779,11 +779,13 @@ mod tests { #[test] fn new() { - let vec = Vec::::new(); + let mut vec = Vec::::new(); assert!(vec.is_empty()); assert!(!vec.is_full()); assert_eq!(vec.len(), 0); assert_eq!(vec.capacity(), 10); + assert_eq!(vec.as_slice(), []); + assert_eq!(vec.as_mut_slice(), []); assert_eq!(DEFAULTS.get(), 0); } @@ -795,11 +797,13 @@ mod tests { #[test] fn default() { - let vec = Vec::::default(); + let mut vec = Vec::::default(); assert!(vec.is_empty()); assert!(!vec.is_full()); assert_eq!(vec.len(), 0); assert_eq!(vec.capacity(), 10); + assert_eq!(vec.as_slice(), []); + assert_eq!(vec.as_mut_slice(), []); assert_eq!(DEFAULTS.get(), 0); } @@ -812,7 +816,6 @@ mod tests { #[test] fn capacity() { let mut vec = Vec::::new(); - assert_eq!(vec.capacity(), 3); vec.set_len(2).unwrap(); @@ -820,12 +823,14 @@ mod tests { vec.push(1).unwrap(); assert_eq!(vec.capacity(), 3); + + vec.clear(); + assert_eq!(vec.capacity(), 3); } #[test] fn len() { let mut vec = Vec::::new(); - assert_eq!(vec.len(), 0); vec.set_len(2).unwrap(); @@ -841,7 +846,6 @@ mod tests { #[test] fn is_empty() { let mut vec = Vec::::new(); - assert!(vec.is_empty()); vec.push(1).unwrap(); @@ -857,7 +861,6 @@ mod tests { #[test] fn is_full() { let mut vec = Vec::::new(); - assert!(!vec.is_full()); vec.push(1).unwrap(); @@ -868,6 +871,11 @@ mod tests { vec.clear(); assert!(!vec.is_full()); + + vec.push(1).unwrap(); + vec.push(1).unwrap(); + vec.push(1).unwrap(); + assert!(vec.is_full()); } #[test] @@ -913,6 +921,7 @@ mod tests { assert_eq!(vec.capacity(), 3); assert!(!vec.is_empty()); assert!(vec.is_full()); + assert_eq!(vec.as_slice(), &[1, 2, 3]); vec.clear(); @@ -920,6 +929,7 @@ mod tests { assert_eq!(vec.capacity(), 3); assert!(vec.is_empty()); assert!(!vec.is_full()); + assert_eq!(vec.as_slice(), &[]); } #[test] @@ -944,12 +954,14 @@ mod tests { fn set_len() { let mut vec = Vec::::new(); + // New length less than capacity assert!(vec.set_len(1).is_ok()); assert_eq!(vec.len(), 1); assert!(!vec.is_empty()); assert!(!vec.is_full()); assert_eq!(vec.as_slice(), [0]); + // New length larger than capacity assert!(matches!(vec.set_len(100), Err(CapacityError))); assert_eq!(format!("{}", vec.set_len(100).unwrap_err()), "vector needs larger capacity"); assert_is_core_error::(); @@ -958,6 +970,7 @@ mod tests { assert!(!vec.is_full()); assert_eq!(vec.as_slice(), [0]); + // New length equal to capacity vec.clear(); vec.set_len(vec.capacity()).unwrap(); assert_eq!(vec.len(), 3); @@ -965,6 +978,7 @@ mod tests { assert!(vec.is_full()); assert_eq!(vec.as_slice(), [0, 0, 0]); + // New length zero assert!(vec.set_len(0).is_ok()); assert_eq!(vec.len(), 0); assert!(vec.is_empty()); @@ -1045,7 +1059,7 @@ mod tests { vec.push(2).unwrap(); vec.push(3).unwrap(); - assert_eq!(vec.first().unwrap(), &1); + assert_eq!(vec.first(), Some(&1)); } #[test] @@ -1061,6 +1075,7 @@ mod tests { assert_eq!(vec.first_mut().unwrap(), &1); *vec.first_mut().unwrap() = 4; + assert_eq!(vec.first_mut(), Some(&mut 4)); assert_eq!(vec.as_slice(), [4, 2, 3]); } @@ -1098,6 +1113,7 @@ mod tests { vec.set_len(1).unwrap(); assert_eq!(vec.last_mut(), Some(&mut 1)); + assert_eq!(vec.as_slice(), [1]); } #[test] @@ -1405,6 +1421,7 @@ mod tests { assert_eq!(CLONES.get(), 3); // the three clones before push } + #[derive(Debug)] struct Struct { i: i32, } @@ -1434,4 +1451,10 @@ mod tests { DROPS.set(DROPS.get() + 1); } } + + impl PartialEq for Struct { + fn eq(&self, other: &Self) -> bool { + self.i == other.i + } + } } From 96acbad274edcbce8d96b7dbdbfa62a447eb573c Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Mon, 26 May 2025 15:58:47 +0300 Subject: [PATCH 5/5] Test eq --- src/lib.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a7efc3b..db85540 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -896,20 +896,25 @@ mod tests { #[test] fn push_should_not_create_default_elements() { let mut vec = Vec::::new(); + vec.push(Struct { i: 0 }).unwrap(); + assert_eq!(DEFAULTS.get(), 0); + assert_eq!(vec.as_slice(), &[Struct { i: 0 }]); } #[test] fn push_should_not_clone_element() { let mut vec = Vec::::new(); - vec.push(Struct { i: 0 }).unwrap(); + vec.push(Struct { i: 1 }).unwrap(); assert_eq!(CLONES.get(), 0); - vec.push(Struct { i: 0 }).unwrap(); - vec.push(Struct { i: 0 }).unwrap(); + vec.push(Struct { i: 2 }).unwrap(); + vec.push(Struct { i: 3 }).unwrap(); assert_eq!(CLONES.get(), 0); + + assert_eq!(vec.as_slice(), &[Struct { i: 1 }, Struct { i: 2 }, Struct { i: 3 }]); } #[test]