diff --git a/gix-object/src/tree/mod.rs b/gix-object/src/tree/mod.rs index be723e1b8df..2bff4bcd90b 100644 --- a/gix-object/src/tree/mod.rs +++ b/gix-object/src/tree/mod.rs @@ -72,7 +72,7 @@ pub struct EntryRef<'a> { pub filename: &'a BStr, /// The id of the object representing the entry. // TODO: figure out how these should be called. id or oid? It's inconsistent around the codebase. - // Answer: make it 'id', as in `git2` + // Answer: make it 'id', as in `git2` #[cfg_attr(feature = "serde", serde(borrow))] pub oid: &'a gix_hash::oid, } @@ -84,11 +84,14 @@ impl<'a> PartialOrd for EntryRef<'a> { } impl<'a> Ord for EntryRef<'a> { - /// Entries compare by the common portion of the filename. This is critical for proper functioning of algorithms working on trees. - /// Doing it like this is needed for compatibility with older, potentially broken(?) trees. - fn cmp(&self, other: &Self) -> Ordering { - let len = self.filename.len().min(other.filename.len()); - self.filename[..len].cmp(&other.filename[..len]) + fn cmp(&self, b: &Self) -> Ordering { + let a = self; + let common = a.filename.len().min(b.filename.len()); + a.filename[..common].cmp(&b.filename[..common]).then_with(|| { + let a = a.filename.get(common).or_else(|| a.mode.is_tree().then_some(&b'/')); + let b = b.filename.get(common).or_else(|| b.mode.is_tree().then_some(&b'/')); + a.cmp(&b) + }) } } @@ -111,12 +114,14 @@ impl PartialOrd for Entry { } impl Ord for Entry { - /// Entries compare by the common portion of the filename. This is critical for proper functioning of algorithms working on trees. - fn cmp(&self, other: &Self) -> Ordering { - let common_len = self.filename.len().min(other.filename.len()); - self.filename[..common_len] - .cmp(&other.filename[..common_len]) - .then_with(|| self.filename.len().cmp(&other.filename.len())) + fn cmp(&self, b: &Self) -> Ordering { + let a = self; + let common = a.filename.len().min(b.filename.len()); + a.filename[..common].cmp(&b.filename[..common]).then_with(|| { + let a = a.filename.get(common).or_else(|| a.mode.is_tree().then_some(&b'/')); + let b = b.filename.get(common).or_else(|| b.mode.is_tree().then_some(&b'/')); + a.cmp(&b) + }) } } diff --git a/gix-object/src/tree/write.rs b/gix-object/src/tree/write.rs index 1e8edc024e0..f826e67499d 100644 --- a/gix-object/src/tree/write.rs +++ b/gix-object/src/tree/write.rs @@ -53,16 +53,16 @@ impl crate::WriteTo for Tree { Ok(()) } + fn kind(&self) -> Kind { + Kind::Tree + } + fn size(&self) -> usize { self.entries .iter() .map(|Entry { mode, filename, oid }| mode.as_bytes().len() + 1 + filename.len() + 1 + oid.as_bytes().len()) .sum() } - - fn kind(&self) -> Kind { - Kind::Tree - } } /// Serialization @@ -96,6 +96,10 @@ impl<'a> crate::WriteTo for TreeRef<'a> { Ok(()) } + fn kind(&self) -> Kind { + Kind::Tree + } + fn size(&self) -> usize { self.entries .iter() @@ -104,8 +108,4 @@ impl<'a> crate::WriteTo for TreeRef<'a> { }) .sum() } - - fn kind(&self) -> Kind { - Kind::Tree - } } diff --git a/gix-object/tests/immutable/commit/from_bytes.rs b/gix-object/tests/commit/from_bytes.rs similarity index 92% rename from gix-object/tests/immutable/commit/from_bytes.rs rename to gix-object/tests/commit/from_bytes.rs index 8c0007122dc..942c7fb4ec6 100644 --- a/gix-object/tests/immutable/commit/from_bytes.rs +++ b/gix-object/tests/commit/from_bytes.rs @@ -2,15 +2,15 @@ use gix_actor::{Sign, SignatureRef, Time}; use gix_object::{bstr::ByteSlice, commit::message::body::TrailerRef, CommitRef}; use smallvec::SmallVec; -use crate::immutable::{ +use crate::{ commit::{LONG_MESSAGE, MERGE_TAG, SIGNATURE}, - fixture_bytes, linus_signature, signature, + fixture_name, linus_signature, signature, }; #[test] fn unsigned() -> crate::Result { assert_eq!( - CommitRef::from_bytes(&fixture_bytes("commit", "unsigned.txt"))?, + CommitRef::from_bytes(&fixture_name("commit", "unsigned.txt"))?, CommitRef { tree: b"1b2dfb4ac5e42080b682fc676e9738c94ce6d54d".as_bstr(), parents: SmallVec::default(), @@ -27,7 +27,7 @@ fn unsigned() -> crate::Result { #[test] fn whitespace() -> crate::Result { assert_eq!( - CommitRef::from_bytes(&fixture_bytes("commit", "whitespace.txt"))?, + CommitRef::from_bytes(&fixture_name("commit", "whitespace.txt"))?, CommitRef { tree: b"9bed6275068a0575243ba8409253e61af81ab2ff".as_bstr(), parents: SmallVec::from(vec![b"26b4df046d1776c123ac69d918f5aec247b58cc6".as_bstr()]), @@ -44,7 +44,7 @@ fn whitespace() -> crate::Result { #[test] fn signed_singleline() -> crate::Result { assert_eq!( - CommitRef::from_bytes(&fixture_bytes("commit", "signed-singleline.txt"))?, + CommitRef::from_bytes(&fixture_name("commit", "signed-singleline.txt"))?, CommitRef { tree: b"00fc39317701176e326974ce44f5bd545a32ec0b".as_bstr(), parents: SmallVec::from(vec![b"09d8d3a12e161a7f6afb522dbe8900a9c09bce06".as_bstr()]), @@ -60,7 +60,7 @@ fn signed_singleline() -> crate::Result { #[test] fn mergetag() -> crate::Result { - let fixture = fixture_bytes("commit", "mergetag.txt"); + let fixture = fixture_name("commit", "mergetag.txt"); let commit = CommitRef { tree: b"1c61918031bf2c7fab9e17dde3c52a6a9884fcb5".as_bstr(), parents: SmallVec::from(vec![ @@ -85,7 +85,7 @@ fn mergetag() -> crate::Result { #[test] fn signed() -> crate::Result { assert_eq!( - CommitRef::from_bytes(&fixture_bytes("commit", "signed.txt"))?, + CommitRef::from_bytes(&fixture_name("commit", "signed.txt"))?, CommitRef { tree: b"00fc39317701176e326974ce44f5bd545a32ec0b".as_bstr(), parents: SmallVec::from(vec![b"09d8d3a12e161a7f6afb522dbe8900a9c09bce06".as_bstr()]), @@ -102,7 +102,7 @@ fn signed() -> crate::Result { #[test] fn signed_with_encoding() -> crate::Result { assert_eq!( - CommitRef::from_bytes(&fixture_bytes("commit", "signed-with-encoding.txt"))?, + CommitRef::from_bytes(&fixture_name("commit", "signed-with-encoding.txt"))?, CommitRef { tree: b"1973afa74d87b2bb73fa884aaaa8752aec43ea88".as_bstr(), parents: SmallVec::from(vec![b"79c51cc86923e2b8ca0ee5c4eb75e48027133f9a".as_bstr()]), @@ -119,7 +119,7 @@ fn signed_with_encoding() -> crate::Result { #[test] fn with_encoding() -> crate::Result { assert_eq!( - CommitRef::from_bytes(&fixture_bytes("commit", "with-encoding.txt"))?, + CommitRef::from_bytes(&fixture_name("commit", "with-encoding.txt"))?, CommitRef { tree: b"4a1c03029e7407c0afe9fc0320b3258e188b115e".as_bstr(), parents: SmallVec::from(vec![b"7ca98aad461a5c302cb4c9e3acaaa6053cc67a62".as_bstr()]), @@ -144,7 +144,7 @@ fn with_trailer() -> crate::Result { sign: Sign::Plus, }, }; - let backing = fixture_bytes("commit", "message-with-footer.txt"); + let backing = fixture_name("commit", "message-with-footer.txt"); let commit = CommitRef::from_bytes(&backing)?; assert_eq!( commit, @@ -224,7 +224,7 @@ instead of depending directly on the lower-level crates. #[test] fn merge() -> crate::Result { assert_eq!( - CommitRef::from_bytes(&fixture_bytes("commit", "merge.txt"))?, + CommitRef::from_bytes(&fixture_name("commit", "merge.txt"))?, CommitRef { tree: b"0cf16ce8e229b59a761198975f0c0263229faf82".as_bstr(), parents: SmallVec::from(vec![ @@ -255,7 +255,7 @@ iyBBl69jASy41Ug/BlFJbw4+ItkShpXwkJKuBBV/JExChmvbxYWaS7QnyYC9UO0= #[test] fn newline_right_after_signature_multiline_header() -> crate::Result { - let fixture = fixture_bytes("commit", "signed-whitespace.txt"); + let fixture = fixture_name("commit", "signed-whitespace.txt"); let commit = CommitRef::from_bytes(&fixture)?; let pgp_sig = OTHER_SIGNATURE.as_bstr(); assert_eq!(commit.extra_headers[0].1.as_ref(), pgp_sig); diff --git a/gix-object/tests/immutable/commit/iter.rs b/gix-object/tests/commit/iter.rs similarity index 85% rename from gix-object/tests/immutable/commit/iter.rs rename to gix-object/tests/commit/iter.rs index 51de47acaf9..c701eeb8aa8 100644 --- a/gix-object/tests/immutable/commit/iter.rs +++ b/gix-object/tests/commit/iter.rs @@ -1,16 +1,13 @@ use gix_object::{bstr::ByteSlice, commit::ref_iter::Token, CommitRefIter}; use crate::{ - hex_to_id, - immutable::{ - commit::{LONG_MESSAGE, MERGE_TAG, SIGNATURE}, - fixture_bytes, linus_signature, signature, - }, + commit::{LONG_MESSAGE, MERGE_TAG, SIGNATURE}, + fixture_name, hex_to_id, linus_signature, signature, }; #[test] fn newline_right_after_signature_multiline_header() -> crate::Result { - let data = fixture_bytes("commit", "signed-whitespace.txt"); + let data = fixture_name("commit", "signed-whitespace.txt"); let tokens = CommitRefIter::from_bytes(&data).collect::, _>>()?; assert_eq!(tokens.len(), 7, "mainly a parsing exercise"); match tokens.last().expect("there are tokens") { @@ -24,7 +21,7 @@ fn newline_right_after_signature_multiline_header() -> crate::Result { #[test] fn signed_with_encoding() -> crate::Result { - let input = fixture_bytes("commit", "signed-with-encoding.txt"); + let input = fixture_name("commit", "signed-with-encoding.txt"); let iter = CommitRefIter::from_bytes(&input); assert_eq!( iter.collect::, _>>()?, @@ -55,7 +52,7 @@ fn signed_with_encoding() -> crate::Result { #[test] fn whitespace() -> crate::Result { assert_eq!( - CommitRefIter::from_bytes(&fixture_bytes("commit", "whitespace.txt")).collect::, _>>()?, + CommitRefIter::from_bytes(&fixture_name("commit", "whitespace.txt")).collect::, _>>()?, vec![ Token::Tree { id: hex_to_id("9bed6275068a0575243ba8409253e61af81ab2ff") @@ -78,7 +75,7 @@ fn whitespace() -> crate::Result { #[test] fn unsigned() -> crate::Result { assert_eq!( - CommitRefIter::from_bytes(&fixture_bytes("commit", "unsigned.txt")).collect::, _>>()?, + CommitRefIter::from_bytes(&fixture_name("commit", "unsigned.txt")).collect::, _>>()?, vec![ Token::Tree { id: hex_to_id("1b2dfb4ac5e42080b682fc676e9738c94ce6d54d") @@ -98,7 +95,7 @@ fn unsigned() -> crate::Result { #[test] fn signed_singleline() -> crate::Result { assert_eq!( - CommitRefIter::from_bytes(&fixture_bytes("commit", "signed-singleline.txt")).collect::, _>>()?, + CommitRefIter::from_bytes(&fixture_name("commit", "signed-singleline.txt")).collect::, _>>()?, vec![ Token::Tree { id: hex_to_id("00fc39317701176e326974ce44f5bd545a32ec0b") @@ -117,7 +114,7 @@ fn signed_singleline() -> crate::Result { ] ); assert_eq!( - CommitRefIter::from_bytes(&fixture_bytes("commit", "signed-singleline.txt")) + CommitRefIter::from_bytes(&fixture_name("commit", "signed-singleline.txt")) .parent_ids() .collect::>(), vec![hex_to_id("09d8d3a12e161a7f6afb522dbe8900a9c09bce06")] @@ -127,7 +124,7 @@ fn signed_singleline() -> crate::Result { #[test] fn error_handling() -> crate::Result { - let data = fixture_bytes("commit", "unsigned.txt"); + let data = fixture_name("commit", "unsigned.txt"); let iter = CommitRefIter::from_bytes(&data[..data.len() / 2]); let tokens = iter.collect::>(); assert!( @@ -139,7 +136,7 @@ fn error_handling() -> crate::Result { #[test] fn mergetag() -> crate::Result { - let input = fixture_bytes("commit", "mergetag.txt"); + let input = fixture_name("commit", "mergetag.txt"); let iter = CommitRefIter::from_bytes(&input); assert_eq!( iter.collect::, _>>()?, @@ -177,14 +174,11 @@ fn mergetag() -> crate::Result { mod method { use gix_object::CommitRefIter; - use crate::{ - hex_to_id, - immutable::{fixture_bytes, signature}, - }; + use crate::{fixture_name, hex_to_id, signature}; #[test] fn tree_id() -> crate::Result { - let input = fixture_bytes("commit", "unsigned.txt"); + let input = fixture_name("commit", "unsigned.txt"); let iter = CommitRefIter::from_bytes(&input); assert_eq!( iter.clone().tree_id().ok(), @@ -200,7 +194,7 @@ mod method { #[test] fn signatures() -> crate::Result { - let input = fixture_bytes("commit", "unsigned.txt"); + let input = fixture_name("commit", "unsigned.txt"); let iter = CommitRefIter::from_bytes(&input); assert_eq!( iter.signatures().collect::>(), diff --git a/gix-object/tests/immutable/commit/message.rs b/gix-object/tests/commit/message.rs similarity index 100% rename from gix-object/tests/immutable/commit/message.rs rename to gix-object/tests/commit/message.rs diff --git a/gix-object/tests/immutable/commit/mod.rs b/gix-object/tests/commit/mod.rs similarity index 98% rename from gix-object/tests/immutable/commit/mod.rs rename to gix-object/tests/commit/mod.rs index 806c1046004..e939618a565 100644 --- a/gix-object/tests/immutable/commit/mod.rs +++ b/gix-object/tests/commit/mod.rs @@ -134,11 +134,11 @@ mod method { use gix_object::CommitRef; use pretty_assertions::assert_eq; - use crate::{hex_to_id, immutable::fixture_bytes}; + use crate::{fixture_name, hex_to_id}; #[test] fn tree() -> crate::Result { - let fixture = fixture_bytes("commit", "unsigned.txt"); + let fixture = fixture_name("commit", "unsigned.txt"); let commit = CommitRef::from_bytes(&fixture)?; assert_eq!(commit.tree(), hex_to_id("1b2dfb4ac5e42080b682fc676e9738c94ce6d54d")); assert_eq!(commit.tree, "1b2dfb4ac5e42080b682fc676e9738c94ce6d54d"); diff --git a/gix-object/tests/encode/mod.rs b/gix-object/tests/encode/mod.rs index d00f60782ca..f9553f6683a 100644 --- a/gix-object/tests/encode/mod.rs +++ b/gix-object/tests/encode/mod.rs @@ -95,3 +95,26 @@ mod blob { // It doesn't matter which data we use - it's not interpreted. round_trip!(gix_object::Blob, gix_object::BlobRef, "tree/everything.tree"); } + +mod loose_header { + use bstr::ByteSlice; + use gix_object::{decode, encode, Kind}; + + #[test] + fn round_trip() -> Result<(), Box> { + for (kind, size, expected) in &[ + (Kind::Tree, 1234, "tree 1234\0".as_bytes()), + (Kind::Blob, 0, b"blob 0\0"), + (Kind::Commit, 24241, b"commit 24241\0"), + (Kind::Tag, 9999999999, b"tag 9999999999\0"), + ] { + let buf = encode::loose_header(*kind, *size); + assert_eq!(buf.as_bstr(), expected.as_bstr()); + let (actual_kind, actual_size, actual_read) = decode::loose_header(&buf)?; + assert_eq!(actual_kind, *kind); + assert_eq!(actual_size, *size); + assert_eq!(actual_read, buf.len()); + } + Ok(()) + } +} diff --git a/gix-object/tests/fixtures/generated-archives/make_trees.tar.xz b/gix-object/tests/fixtures/generated-archives/make_trees.tar.xz new file mode 100644 index 00000000000..0a5cd2f67a2 --- /dev/null +++ b/gix-object/tests/fixtures/generated-archives/make_trees.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d0ebc472023fffe49d71303e5f41f8c6ca24e28d283468f2426791c6286ecf7 +size 10240 diff --git a/gix-object/tests/fixtures/make_trees.sh b/gix-object/tests/fixtures/make_trees.sh new file mode 100644 index 00000000000..74b282cbb30 --- /dev/null +++ b/gix-object/tests/fixtures/make_trees.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -eu -o pipefail + +function baseline() { + local revspec=${1:?First argument is the revspec of the object to create a baseline for} + local basename=${2:?Second argument is the name of the baseline file} + local baseline_file="$basename.baseline" + git rev-parse "$revspec" | git cat-file --batch | tail -n +2 > "$baseline_file" + truncate -s "$(($(stat -c '%s' "$baseline_file")-1))" "$baseline_file" +} + +git init -q +mkdir file +touch bin bin.d file.to file.toml file.toml.bin file0 file/a + +git add . +git commit -m "c1" + +baseline @^{tree} tree diff --git a/gix-object/tests/immutable/mod.rs b/gix-object/tests/immutable/mod.rs deleted file mode 100644 index ba4c4f34151..00000000000 --- a/gix-object/tests/immutable/mod.rs +++ /dev/null @@ -1,50 +0,0 @@ -use std::path::PathBuf; - -use gix_actor::{Sign, Time}; - -mod commit; -mod tag; -mod tree; - -#[cfg(not(windows))] -fn fixup(v: Vec) -> Vec { - v -} - -#[cfg(windows)] -fn fixup(v: Vec) -> Vec { - // Git checks out text files with line ending conversions, git itself will of course not put '\r\n' anywhere, - // so that wouldn't be expected in an object and doesn't have to be parsed. - use bstr::ByteSlice; - v.replace(b"\r\n", "\n") -} - -fn fixture_bytes(kind: &str, path: &str) -> Vec { - fixup(super::fixture_bytes(PathBuf::from(kind).join(path).to_str().unwrap())) -} - -fn signature(time: u32) -> gix_actor::SignatureRef<'static> { - use gix_object::bstr::ByteSlice; - gix_actor::SignatureRef { - name: b"Sebastian Thiel".as_bstr(), - email: b"sebastian.thiel@icloud.com".as_bstr(), - time: Time { - seconds_since_unix_epoch: time, - offset_in_seconds: 28800, - sign: Sign::Plus, - }, - } -} - -fn linus_signature(time: u32) -> gix_actor::SignatureRef<'static> { - use gix_object::bstr::ByteSlice; - gix_actor::SignatureRef { - name: b"Linus Torvalds".as_bstr(), - email: b"torvalds@linux-foundation.org".as_bstr(), - time: Time { - seconds_since_unix_epoch: time, - offset_in_seconds: -25200, - sign: Sign::Minus, - }, - } -} diff --git a/gix-object/tests/loose/mod.rs b/gix-object/tests/loose/mod.rs deleted file mode 100644 index 3752853859a..00000000000 --- a/gix-object/tests/loose/mod.rs +++ /dev/null @@ -1,28 +0,0 @@ -use bstr::ByteSlice; -use gix_object::{decode, encode, Kind, ObjectRef}; - -#[test] -fn all() -> Result<(), Box> { - for (kind, size, expected) in &[ - (Kind::Tree, 1234, "tree 1234\0".as_bytes()), - (Kind::Blob, 0, b"blob 0\0"), - (Kind::Commit, 24241, b"commit 24241\0"), - (Kind::Tag, 9999999999, b"tag 9999999999\0"), - ] { - let buf = encode::loose_header(*kind, *size); - assert_eq!(buf.as_bstr(), expected.as_bstr()); - let (actual_kind, actual_size, actual_read) = decode::loose_header(&buf)?; - assert_eq!(actual_kind, *kind); - assert_eq!(actual_size, *size); - assert_eq!(actual_read, buf.len()); - } - Ok(()) -} - -#[test] -fn shorter_than_advertised() { - assert_eq!( - ObjectRef::from_loose(b"tree 1000\x00").unwrap_err().to_string(), - "object data was shorter than its size declared in the header" - ); -} diff --git a/gix-object/tests/object.rs b/gix-object/tests/object.rs index ed537f2339e..b323911a559 100644 --- a/gix-object/tests/object.rs +++ b/gix-object/tests/object.rs @@ -1,10 +1,12 @@ -use std::path::PathBuf; - use gix_hash::ObjectId; +use std::path::PathBuf; + +mod commit; mod encode; -mod immutable; -mod loose; +mod object_ref; +mod tag; +mod tree; #[test] fn compute_hash() { @@ -42,6 +44,10 @@ fn fixture_bytes(path: &str) -> Vec { fixup(std::fs::read(fixture(path)).unwrap()) } +fn fixture_name(kind: &str, path: &str) -> Vec { + fixup(fixture_bytes(PathBuf::from(kind).join(path).to_str().unwrap())) +} + #[test] fn size_in_memory() { let actual = std::mem::size_of::(); @@ -54,3 +60,31 @@ fn size_in_memory() { fn hex_to_id(hex: &str) -> ObjectId { ObjectId::from_hex(hex.as_bytes()).expect("40 bytes hex") } + +use gix_actor::{Sign, Time}; + +fn signature(time: u32) -> gix_actor::SignatureRef<'static> { + use gix_object::bstr::ByteSlice; + gix_actor::SignatureRef { + name: b"Sebastian Thiel".as_bstr(), + email: b"sebastian.thiel@icloud.com".as_bstr(), + time: Time { + seconds_since_unix_epoch: time, + offset_in_seconds: 28800, + sign: Sign::Plus, + }, + } +} + +fn linus_signature(time: u32) -> gix_actor::SignatureRef<'static> { + use gix_object::bstr::ByteSlice; + gix_actor::SignatureRef { + name: b"Linus Torvalds".as_bstr(), + email: b"torvalds@linux-foundation.org".as_bstr(), + time: Time { + seconds_since_unix_epoch: time, + offset_in_seconds: -25200, + sign: Sign::Minus, + }, + } +} diff --git a/gix-object/tests/object_ref/mod.rs b/gix-object/tests/object_ref/mod.rs new file mode 100644 index 00000000000..d1285947bf8 --- /dev/null +++ b/gix-object/tests/object_ref/mod.rs @@ -0,0 +1,11 @@ +mod from_loose { + use gix_object::ObjectRef; + + #[test] + fn shorter_than_advertised() { + assert_eq!( + ObjectRef::from_loose(b"tree 1000\x00").unwrap_err().to_string(), + "object data was shorter than its size declared in the header" + ); + } +} diff --git a/gix-object/tests/immutable/tag.rs b/gix-object/tests/tag/mod.rs similarity index 88% rename from gix-object/tests/immutable/tag.rs rename to gix-object/tests/tag/mod.rs index 630361d7afe..0531bb67a0e 100644 --- a/gix-object/tests/immutable/tag.rs +++ b/gix-object/tests/tag/mod.rs @@ -4,11 +4,11 @@ mod method { use gix_object::TagRef; use pretty_assertions::assert_eq; - use crate::{hex_to_id, immutable::fixture_bytes}; + use crate::{fixture_name, hex_to_id}; #[test] fn target() -> crate::Result { - let fixture = fixture_bytes("tag", "signed.txt"); + let fixture = fixture_name("tag", "signed.txt"); let tag = TagRef::from_bytes(&fixture)?; assert_eq!(tag.target(), hex_to_id("ffa700b4aca13b80cb6b98a078e7c96804f8e0ec")); assert_eq!(tag.target, "ffa700b4aca13b80cb6b98a078e7c96804f8e0ec".as_bytes()); @@ -19,14 +19,11 @@ mod method { mod iter { use gix_object::{bstr::ByteSlice, tag::ref_iter::Token, Kind, TagRefIter}; - use crate::{ - hex_to_id, - immutable::{fixture_bytes, signature}, - }; + use crate::{fixture_name, hex_to_id, signature}; #[test] fn empty() -> crate::Result { - let tag = fixture_bytes("tag", "empty.txt"); + let tag = fixture_name("tag", "empty.txt"); let tag_iter = TagRefIter::from_bytes(&tag); let target_id = hex_to_id("01dd4e2a978a9f5bd773dae6da7aa4a5ac1cdbbc"); let tagger = Some(signature(1592381636)); @@ -51,7 +48,7 @@ mod iter { #[test] fn no_tagger() -> crate::Result { assert_eq!( - TagRefIter::from_bytes(&fixture_bytes("tag", "no-tagger.txt")).collect::, _>>()?, + TagRefIter::from_bytes(&fixture_name("tag", "no-tagger.txt")).collect::, _>>()?, vec![ Token::Target { id: hex_to_id("c39ae07f393806ccf406ef966e9a15afc43cc36a") @@ -87,7 +84,7 @@ KLMHist5yj0sw1E4hDTyQa0= #[test] fn whitespace() -> crate::Result { assert_eq!( - TagRefIter::from_bytes(&fixture_bytes("tag", "whitespace.txt")).collect::, _>>()?, + TagRefIter::from_bytes(&fixture_name("tag", "whitespace.txt")).collect::, _>>()?, vec![ Token::Target { id: hex_to_id("01dd4e2a978a9f5bd773dae6da7aa4a5ac1cdbbc") @@ -106,7 +103,7 @@ KLMHist5yj0sw1E4hDTyQa0= #[test] fn error_handling() -> crate::Result { - let data = fixture_bytes("tag", "empty.txt"); + let data = fixture_name("tag", "empty.txt"); let iter = TagRefIter::from_bytes(&data[..data.len() / 3]); let tokens = iter.collect::>(); assert!( @@ -120,12 +117,12 @@ KLMHist5yj0sw1E4hDTyQa0= mod from_bytes { use gix_object::{bstr::ByteSlice, Kind, TagRef}; - use crate::immutable::{fixture_bytes, signature, tag::tag_fixture}; + use crate::{fixture_name, signature, tag::tag_fixture}; #[test] fn signed() -> crate::Result { assert_eq!( - TagRef::from_bytes(&fixture_bytes("tag", "signed.txt"))?, + TagRef::from_bytes(&fixture_name("tag", "signed.txt"))?, tag_fixture(9000) ); Ok(()) @@ -134,7 +131,7 @@ mod from_bytes { #[test] fn empty() -> crate::Result { assert_eq!( - TagRef::from_bytes(&fixture_bytes("tag", "empty.txt"))?, + TagRef::from_bytes(&fixture_name("tag", "empty.txt"))?, TagRef { target: b"01dd4e2a978a9f5bd773dae6da7aa4a5ac1cdbbc".as_bstr(), name: b"empty".as_bstr(), @@ -150,7 +147,7 @@ mod from_bytes { #[test] fn with_newlines() -> crate::Result { assert_eq!( - TagRef::from_bytes(&fixture_bytes("tag", "with-newlines.txt"))?, + TagRef::from_bytes(&fixture_name("tag", "with-newlines.txt"))?, TagRef { target: b"ebdf205038b66108c0331aa590388431427493b7".as_bstr(), name: b"baz".as_bstr(), @@ -166,7 +163,7 @@ mod from_bytes { #[test] fn no_tagger() -> crate::Result { assert_eq!( - TagRef::from_bytes(&fixture_bytes("tag", "no-tagger.txt"))?, + TagRef::from_bytes(&fixture_name("tag", "no-tagger.txt"))?, TagRef { target: b"c39ae07f393806ccf406ef966e9a15afc43cc36a".as_bstr(), name: b"v2.6.11-tree".as_bstr(), @@ -198,7 +195,7 @@ KLMHist5yj0sw1E4hDTyQa0= #[test] fn whitespace() -> crate::Result { assert_eq!( - TagRef::from_bytes(&fixture_bytes("tag", "whitespace.txt"))?, + TagRef::from_bytes(&fixture_name("tag", "whitespace.txt"))?, TagRef { target: b"01dd4e2a978a9f5bd773dae6da7aa4a5ac1cdbbc".as_bstr(), name: b"whitespace".as_bstr(), diff --git a/gix-object/tests/immutable/tree.rs b/gix-object/tests/tree/mod.rs similarity index 79% rename from gix-object/tests/immutable/tree.rs rename to gix-object/tests/tree/mod.rs index 1cb66ef39ce..5e5515bb6c9 100644 --- a/gix-object/tests/immutable/tree.rs +++ b/gix-object/tests/tree/mod.rs @@ -1,7 +1,7 @@ mod iter { use gix_object::{bstr::ByteSlice, tree, tree::EntryRef, TreeRefIter}; - use crate::{hex_to_id, immutable::fixture_bytes}; + use crate::{fixture_name, hex_to_id}; #[test] fn empty() { @@ -10,7 +10,7 @@ mod iter { #[test] fn error_handling() { - let data = fixture_bytes("tree", "everything.tree"); + let data = fixture_name("tree", "everything.tree"); let iter = TreeRefIter::from_bytes(&data[..data.len() / 2]); let entries = iter.collect::>(); assert!( @@ -22,7 +22,7 @@ mod iter { #[test] fn everything() -> crate::Result { assert_eq!( - TreeRefIter::from_bytes(&fixture_bytes("tree", "everything.tree")).collect::, _>>()?, + TreeRefIter::from_bytes(&fixture_name("tree", "everything.tree")).collect::, _>>()?, vec![ EntryRef { mode: tree::EntryMode::BlobExecutable, @@ -58,7 +58,7 @@ mod iter { mod from_bytes { use gix_object::{bstr::ByteSlice, tree, tree::EntryRef, TreeRef}; - use crate::{hex_to_id, immutable::fixture_bytes}; + use crate::{fixture_name, hex_to_id}; #[test] fn empty() -> crate::Result { @@ -73,7 +73,7 @@ mod from_bytes { #[test] fn everything() -> crate::Result { assert_eq!( - TreeRef::from_bytes(&fixture_bytes("tree", "everything.tree"))?, + TreeRef::from_bytes(&fixture_name("tree", "everything.tree"))?, TreeRef { entries: vec![ EntryRef { @@ -110,7 +110,7 @@ mod from_bytes { #[test] fn maybe_special() -> crate::Result { assert_eq!( - TreeRef::from_bytes(&fixture_bytes("tree", "maybe-special.tree"))? + TreeRef::from_bytes(&fixture_name("tree", "maybe-special.tree"))? .entries .len(), 160 @@ -121,7 +121,7 @@ mod from_bytes { #[test] fn definitely_special() -> crate::Result { assert_eq!( - TreeRef::from_bytes(&fixture_bytes("tree", "definitely-special.tree"))? + TreeRef::from_bytes(&fixture_name("tree", "definitely-special.tree"))? .entries .len(), 19 @@ -130,6 +130,29 @@ mod from_bytes { } } +mod entries { + use gix_object::{Tree, TreeRef}; + + #[test] + fn sort_order_is_correct() -> crate::Result { + let root = gix_testtools::scripted_fixture_read_only("make_trees.sh")?; + let input = std::fs::read(root.join("tree.baseline"))?; + + let mut tree = TreeRef::from_bytes(&input)?; + let expected = tree.entries.clone(); + + tree.entries.sort(); + assert_eq!(tree.entries, expected); + + let mut tree: Tree = tree.into(); + let expected = tree.entries.clone(); + tree.entries.sort(); + + assert_eq!(tree.entries, expected); + Ok(()) + } +} + mod entry_mode { use gix_object::tree::EntryMode;