From 210c661d987b6835cc028b2acd2e08264ae9d1db Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 31 Dec 2023 13:10:40 -0800 Subject: [PATCH 1/3] tree: tests: Make the test tree have 8 entries, to allow more thorough testing This will allow testing advancement by more than 1 at a time. --- src/tree.rs | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/tree.rs b/src/tree.rs index 9a38244cfa..55f0254500 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -472,7 +472,7 @@ mod tests { let tree = repo.find_tree(commit.tree_id()).unwrap(); assert_eq!(tree.id(), commit.tree_id()); - assert_eq!(tree.len(), 1); + assert_eq!(tree.len(), 8); for entry in tree_iter(&tree, &repo) { println!("iter entry {:?}", entry.name()); @@ -481,11 +481,14 @@ mod tests { fn setup_repo(td: &TempDir, repo: &Repository) { let mut index = repo.index().unwrap(); - File::create(&td.path().join("foo")) - .unwrap() - .write_all(b"foo") - .unwrap(); - index.add_path(Path::new("foo")).unwrap(); + for n in 0..8 { + let name = format!("f{n}"); + File::create(&td.path().join(&name)) + .unwrap() + .write_all(name.as_bytes()) + .unwrap(); + index.add_path(Path::new(&name)).unwrap(); + } let id = index.write_tree().unwrap(); let sig = repo.signature().unwrap(); let tree = repo.find_tree(id).unwrap(); @@ -515,14 +518,22 @@ mod tests { let tree = repo.find_tree(commit.tree_id()).unwrap(); assert_eq!(tree.id(), commit.tree_id()); - assert_eq!(tree.len(), 1); + assert_eq!(tree.len(), 8); { - let e1 = tree.get(0).unwrap(); + let e0 = tree.get(0).unwrap(); + assert!(e0 == tree.get_id(e0.id()).unwrap()); + assert!(e0 == tree.get_name("f0").unwrap()); + assert!(e0 == tree.get_name_bytes(b"f0").unwrap()); + assert!(e0 == tree.get_path(Path::new("f0")).unwrap()); + assert_eq!(e0.name(), Some("f0")); + e0.to_object(&repo).unwrap(); + + let e1 = tree.get(1).unwrap(); assert!(e1 == tree.get_id(e1.id()).unwrap()); - assert!(e1 == tree.get_name("foo").unwrap()); - assert!(e1 == tree.get_name_bytes(b"foo").unwrap()); - assert!(e1 == tree.get_path(Path::new("foo")).unwrap()); - assert_eq!(e1.name(), Some("foo")); + assert!(e1 == tree.get_name("f1").unwrap()); + assert!(e1 == tree.get_name_bytes(b"f1").unwrap()); + assert!(e1 == tree.get_path(Path::new("f1")).unwrap()); + assert_eq!(e1.name(), Some("f1")); e1.to_object(&repo).unwrap(); } tree.into_object(); @@ -551,20 +562,20 @@ mod tests { let mut ct = 0; tree.walk(TreeWalkMode::PreOrder, |_, entry| { - assert_eq!(entry.name(), Some("foo")); + assert_eq!(entry.name(), Some(format!("f{ct}").as_str())); ct += 1; 0 }) .unwrap(); - assert_eq!(ct, 1); + assert_eq!(ct, 8); let mut ct = 0; tree.walk(TreeWalkMode::PreOrder, |_, entry| { - assert_eq!(entry.name(), Some("foo")); + assert_eq!(entry.name(), Some(format!("f{ct}").as_str())); ct += 1; TreeWalkResult::Ok }) .unwrap(); - assert_eq!(ct, 1); + assert_eq!(ct, 8); } } From 2be11ddb5de2fb2023541e13f037d17db5ee52a0 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 31 Dec 2023 13:11:23 -0800 Subject: [PATCH 2/3] tree::TreeIter: Implement `nth` to make jumping ahead more efficient This means `skip` (which uses `nth`) will also be more efficient. --- src/tree.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tree.rs b/src/tree.rs index 55f0254500..a9ddca0802 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -397,6 +397,9 @@ impl<'tree> Iterator for TreeIter<'tree> { fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } + fn nth(&mut self, n: usize) -> Option> { + self.range.nth(n).and_then(|i| self.tree.get(i)) + } } impl<'tree> DoubleEndedIterator for TreeIter<'tree> { fn next_back(&mut self) -> Option> { From 5d0628e6a6958b4695e3b2f50ae29f602d0a1db2 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 31 Dec 2023 13:15:16 -0800 Subject: [PATCH 3/3] tree: tests: Test `TreeIter::nth` --- src/tree.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/tree.rs b/src/tree.rs index a9ddca0802..916cf83c5f 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -482,6 +482,24 @@ mod tests { } } + #[test] + fn smoke_tree_nth() { + let (td, repo) = crate::test::repo_init(); + + setup_repo(&td, &repo); + + let head = repo.head().unwrap(); + let target = head.target().unwrap(); + let commit = repo.find_commit(target).unwrap(); + + let tree = repo.find_tree(commit.tree_id()).unwrap(); + assert_eq!(tree.id(), commit.tree_id()); + assert_eq!(tree.len(), 8); + let mut it = tree.iter(); + let e = it.nth(4).unwrap(); + assert_eq!(e.name(), Some("f4")); + } + fn setup_repo(td: &TempDir, repo: &Repository) { let mut index = repo.index().unwrap(); for n in 0..8 {