171 lines · 5.3 KB · Rust
RawDownload
use gix_object::{    TreeRefIter,    bstr::ByteSlice,    tree::{self, EntryRef},};use pretty_assertions::assert_eq; use crate::{fixture_hash_kind, fixture_oid, tree_fixture}; #[test]fn empty() {    assert_eq!(        TreeRefIter::from_bytes(&[], gix_testtools::object_hash()).count(),        0,        "empty trees are definitely ok"    );} #[test]fn error_handling() {    let data = tree_fixture("everything.tree").expect("fixture is valid");    let iter = TreeRefIter::from_bytes(&data[..data.len() / 2], fixture_hash_kind());    let entries = iter.collect::<Vec<_>>();    assert!(        entries.last().expect("at least one token").is_err(),        "errors are propagated and none is returned from that point on"    );} #[test]fn offset_to_next_entry() {    let hash_kind = fixture_hash_kind();    let buf = tree_fixture("everything.tree").expect("fixture is valid");    let mut iter = TreeRefIter::from_bytes(&buf, hash_kind);    assert_eq!(iter.offset_to_next_entry(&buf), 0, "first entry is always at 0");    iter.next();     let actual = iter.offset_to_next_entry(&buf);    assert_eq!(actual, 11 + hash_kind.len_in_bytes(), "now the offset increases");    assert_eq!(        TreeRefIter::from_bytes(&buf[actual..], hash_kind)            .next()            .map(|e| e.unwrap().filename),        iter.next().map(|e| e.unwrap().filename),        "One can now start the iteration at a certain entry"    );} #[test]fn everything() -> crate::Result {    assert_eq!(        TreeRefIter::from_bytes(&tree_fixture("everything.tree")?, fixture_hash_kind())            .collect::<Result<Vec<_>, _>>()?,        vec![            EntryRef {                mode: tree::EntryKind::BlobExecutable.into(),                filename: b"exe".as_bstr(),                oid: &fixture_oid("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391")            },            EntryRef {                mode: tree::EntryKind::Blob.into(),                filename: b"file".as_bstr(),                oid: &fixture_oid("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391")            },            EntryRef {                mode: tree::EntryKind::Commit.into(),                filename: b"grit-submodule".as_bstr(),                oid: &fixture_oid("b2d1b5d684bdfda5f922b466cc13d4ce2d635cf8")            },            EntryRef {                mode: tree::EntryKind::Tree.into(),                filename: b"subdir".as_bstr(),                oid: &fixture_oid("4d5fcadc293a348e88f777dc0920f11e7d71441c")            },            EntryRef {                mode: tree::EntryKind::Link.into(),                filename: b"symlink".as_bstr(),                oid: &fixture_oid("1a010b1c0f081b2e8901d55307a15c29ff30af0e")            }        ]    );    Ok(())} #[test]fn leading_space_in_tree_name() -> crate::Result {    let oid = fixture_oid("4d5fcadc293a348e88f777dc0920f11e7d71441c");    let mut buf = b"40000  leading space\0".to_vec();    buf.extend_from_slice(oid.as_bytes());     assert_eq!(        TreeRefIter::from_bytes(&buf, fixture_hash_kind()).collect::<Result<Vec<_>, _>>()?,        vec![EntryRef {            mode: tree::EntryKind::Tree.into(),            filename: b" leading space".as_bstr(),            oid: oid.as_ref(),        }]    );    Ok(())} mod lookup_entry {    use gix_object::tree::EntryKind;    use utils::entry;     use crate::fixture_hash_kind;     #[test]    fn top_level_directory() -> crate::Result {        assert_eq!(            utils::lookup_entry_by_path("bin")?,            entry("bin", EntryKind::Blob, fixture_hash_kind().empty_blob())        );        Ok(())    }     #[test]    fn nested_file() -> crate::Result {        assert_eq!(            utils::lookup_entry_by_path("file/a")?,            entry("a", EntryKind::Blob, fixture_hash_kind().empty_blob())        );        Ok(())    }     #[test]    fn non_existing_nested_file() -> crate::Result {        for path in ["file/does-not-exist", "non-existing", "file/a/through-file"] {            let actual = utils::lookup_entry_by_path(path)?;            assert_eq!(actual, None);        }        Ok(())    }     mod utils {        use gix_object::{FindExt, tree};         use crate::generated_tree_root_id;         pub(super) fn entry(filename: &str, mode: tree::EntryKind, oid: gix_hash::ObjectId) -> Option<tree::Entry> {            Some(tree::Entry {                mode: mode.into(),                filename: filename.into(),                oid,            })        }         pub(super) fn tree_odb() -> gix_testtools::Result<gix_odb::Handle> {            let root = gix_testtools::scripted_fixture_read_only("make_trees.sh")?;            Ok(gix_odb::at_opts(                root.join(".git/objects"),                Vec::new(),                gix_odb::store::init::Options {                    object_hash: crate::fixture_hash_kind(),                    ..Default::default()                },            )?)        }         pub(super) fn lookup_entry_by_path(path: &str) -> gix_testtools::Result<Option<gix_object::tree::Entry>> {            let odb = tree_odb()?;            let root_tree_id = generated_tree_root_id()?;             let mut buf = Vec::new();            let root_tree = odb.find_tree_iter(&root_tree_id, &mut buf)?;             let mut buf = Vec::new();            root_tree.lookup_entry_by_path(&odb, &mut buf, path)        }    }}