Bugfix: Rebuild iterator when changing collection

This patch fixes a bug where the following code (here pseudocode) did
the wrong thing:

    store.entries().in_collection("foo").for_each(||...)

because the `.in_collection()` call for the underlying PathIterator
object did not actually re-build the iterator. It only changed the
contained `PathIterBuilder`, but did not call `.build_iter()` on it to
rebuild the iterator object.

The test added with this patch checks whether the iterator does the
right thing.

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
Matthias Beyer 2019-02-15 18:26:57 +01:00
parent 2a07c8a0c2
commit 0916c92a18
2 changed files with 51 additions and 0 deletions

View file

@ -67,6 +67,7 @@ impl PathIterator {
pub fn in_collection(mut self, c: &str) -> Self {
trace!("Generating iterator object for collection: {}", c);
self.iter_builder.in_collection(c);
self.iter = self.iter_builder.build_iter();
self
}

View file

@ -214,3 +214,53 @@ impl<'a> Iterator for Entries<'a> {
}
}
#[cfg(test)]
mod tests {
extern crate env_logger;
use std::path::PathBuf;
use std::sync::Arc;
fn setup_logging() {
let _ = env_logger::try_init();
}
use store::Store;
use storeid::StoreId;
use file_abstraction::InMemoryFileAbstraction;
use libimagutil::variants::generate_variants;
pub fn get_store() -> Store {
let backend = Arc::new(InMemoryFileAbstraction::default());
Store::new_with_backend(PathBuf::from("/"), &None, backend).unwrap()
}
#[test]
fn test_entries_iterator_in_collection() {
setup_logging();
let store = get_store();
let ids = {
let base = String::from("entry");
let variants = vec!["coll_1", "coll_2", "coll_3"];
let modifier = |base: &String, v: &&str| {
StoreId::new(Some(store.path().clone()), PathBuf::from(format!("{}/{}", *v, base))).unwrap()
};
generate_variants(&base, variants.iter(), &modifier)
};
for id in ids {
let _ = store.retrieve(id).unwrap();
}
let succeeded = store.entries()
.unwrap()
.in_collection("coll_3")
.map(|id| { debug!("Processing id = {:?}", id); id })
.all(|id| id.unwrap().is_in_collection(&["coll_3"]));
assert!(succeeded, "not all entries in iterator are from coll_3 collection");
}
}