mod existing { use std::convert::{TryFrom, TryInto}; use git_ref::{PartialName, PartialNameRef}; use git_testtools::hex_to_id; use crate::file::store_at; #[test] fn with_packed_refs() -> crate::Result { let store = store_at("make_packed_ref_repository_for_overlay.sh")?; let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03"); let r = store.find("main")?; assert_eq!(r.target.into_id(), c1); assert_eq!(r.name.as_bstr(), "refs/heads/main"); Ok(()) } // TODO: figure this out #[test] fn possible_inputs() -> crate::Result { let store = crate::file::store()?; store.find_loose("dt1")?; store.find_loose(&String::from("dt1"))?; // Owned Strings don't have an impl for PartialName struct CustomType(String); impl<'a> TryFrom<&'a CustomType> for &'a PartialNameRef { type Error = git_ref::name::Error; fn try_from(value: &'a CustomType) -> Result<Self, Self::Error> { value.0.as_str().try_into() } } store.find_loose(&CustomType("dt1".into()))?; struct CustomName { remote: &'static str, branch: &'static str, } impl CustomName { fn to_partial_name(&self) -> String { format!("{}/{}", self.remote, self.branch) } fn to_partial_name_from_string(&self) -> PartialName { self.to_partial_name().try_into().expect("cannot fail") } fn to_partial_name_from_bstring(&self) -> PartialName { git_object::bstr::BString::from(self.to_partial_name()) .try_into() .expect("cannot fail") } fn to_full_name(&self) -> git_ref::FullName { format!("{}/{}", self.remote, self.branch) .try_into() .expect("always valid") } } impl<'a> TryFrom<&'a CustomName> for PartialName { type Error = git_ref::name::Error; fn try_from(value: &'a CustomName) -> Result<Self, Self::Error> { PartialName::try_from(value.to_partial_name()) } } let name = CustomName { remote: "origin", branch: "main", }; store.find_loose(&name.to_partial_name())?; // TODO: this effectively needs a `Cow<'_, PartialNameRef>`, but we are not allowed to implement conversions for it. // After having been there, I don't want to have a `PartialNameCow(Cow<'_, PartialNameRef)` anymore, nor // copies of `TryFrom/TryInto` traits in our crate. // Make it work once we can implement standard traits for Cow<OurType>. // store.find_loose(&name)?; // store.find_loose(name.to_partial_name())?; store.find_loose(&name.to_partial_name_from_string())?; store.find_loose(&name.to_partial_name_from_bstring())?; store.find_loose(&name.to_full_name())?; store.find_loose(name.to_full_name().as_ref())?; store.find_loose(name.to_full_name().as_ref().as_partial_name())?; store.find_loose(&PartialName::try_from(name.remote)?.join(name.branch)?)?; store.find_loose(&PartialName::try_from("origin")?.join("main")?)?; store.find_loose(&PartialName::try_from("origin")?.join(String::from("main"))?)?; store.find_loose(&PartialName::try_from("origin")?.join("main")?)?; Ok(()) }} mod loose { use crate::file::store; mod existing { use std::path::Path; use crate::file::store; #[test] fn success_and_failure() -> crate::Result { let store = store()?; for (partial_name, expected_path) in &[("main", Some("refs/heads/main")), ("does-not-exist", None)] { let reference = store.find_loose(*partial_name); match expected_path { Some(expected_path) => assert_eq!(reference?.name.as_bstr(), expected_path), None => match reference { Ok(_) => panic!("Expected error"), Err(git_ref::file::find::existing::Error::NotFound(name)) => { assert_eq!(name, Path::new(*partial_name)); } Err(err) => panic!("Unexpected err: {:?}", err), }, } } Ok(()) } } #[test] fn success() -> crate::Result { let store = store()?; for (partial_name, expected_path, expected_ref_kind) in &[ ("dt1", "refs/tags/dt1", git_ref::Kind::Peeled), // tags before heads ("heads/dt1", "refs/heads/dt1", git_ref::Kind::Peeled), ("d1", "refs/d1", git_ref::Kind::Peeled), // direct refs before heads ("heads/d1", "refs/heads/d1", git_ref::Kind::Peeled), ("HEAD", "HEAD", git_ref::Kind::Symbolic), // it finds shortest paths first ("origin", "refs/remotes/origin/HEAD", git_ref::Kind::Symbolic), ("origin/HEAD", "refs/remotes/origin/HEAD", git_ref::Kind::Symbolic), ("origin/main", "refs/remotes/origin/main", git_ref::Kind::Peeled), ("t1", "refs/tags/t1", git_ref::Kind::Peeled), ("main", "refs/heads/main", git_ref::Kind::Peeled), ("heads/main", "refs/heads/main", git_ref::Kind::Peeled), ("refs/heads/main", "refs/heads/main", git_ref::Kind::Peeled), ] { let reference = store.try_find_loose(*partial_name)?.expect("exists"); assert_eq!(reference.name.as_bstr(), expected_path); assert_eq!(reference.target.to_ref().kind(), *expected_ref_kind); } Ok(()) } #[test] fn failure() -> crate::Result { let store = store()?; for (partial_name, reason, is_err) in &[ ("foobar", "does not exist", false), ("broken", "does not parse", true), ("../escaping", "an invalid ref name", true), ] { let reference = store.try_find_loose(*partial_name); if *is_err { assert!(reference.is_err(), "{}", reason); } else { let reference = reference?; assert!(reference.is_none(), "{}", reason); } } Ok(()) }}
mod existing {
use std::convert::{TryFrom, TryInto};
use git_ref::{PartialName, PartialNameRef};
use git_testtools::hex_to_id;
use crate::file::store_at;
#[test]
fn with_packed_refs() -> crate::Result {
let store = store_at("make_packed_ref_repository_for_overlay.sh")?;
let c1 = hex_to_id("134385f6d781b7e97062102c6a483440bfda2a03");
let r = store.find("main")?;
assert_eq!(r.target.into_id(), c1);
assert_eq!(r.name.as_bstr(), "refs/heads/main");
Ok(())
}
// TODO: figure this out
#[test]
fn possible_inputs() -> crate::Result {
let store = crate::file::store()?;
store.find_loose("dt1")?;
store.find_loose(&String::from("dt1"))?; // Owned Strings don't have an impl for PartialName
struct CustomType(String);
impl<'a> TryFrom<&'a CustomType> for &'a PartialNameRef {
type Error = git_ref::name::Error;
fn try_from(value: &'a CustomType) -> Result<Self, Self::Error> {
value.0.as_str().try_into()
}
}
store.find_loose(&CustomType("dt1".into()))?;
struct CustomName {
remote: &'static str,
branch: &'static str,
}
impl CustomName {
fn to_partial_name(&self) -> String {
format!("{}/{}", self.remote, self.branch)
}
fn to_partial_name_from_string(&self) -> PartialName {
self.to_partial_name().try_into().expect("cannot fail")
}
fn to_partial_name_from_bstring(&self) -> PartialName {
git_object::bstr::BString::from(self.to_partial_name())
.try_into()
.expect("cannot fail")
}
fn to_full_name(&self) -> git_ref::FullName {
format!("{}/{}", self.remote, self.branch)
.try_into()
.expect("always valid")
}
}
impl<'a> TryFrom<&'a CustomName> for PartialName {
type Error = git_ref::name::Error;
fn try_from(value: &'a CustomName) -> Result<Self, Self::Error> {
PartialName::try_from(value.to_partial_name())
}
}
let name = CustomName {
remote: "origin",
branch: "main",
};
store.find_loose(&name.to_partial_name())?;
// TODO: this effectively needs a `Cow<'_, PartialNameRef>`, but we are not allowed to implement conversions for it.
// After having been there, I don't want to have a `PartialNameCow(Cow<'_, PartialNameRef)` anymore, nor
// copies of `TryFrom/TryInto` traits in our crate.
// Make it work once we can implement standard traits for Cow<OurType>.
// store.find_loose(&name)?;
// store.find_loose(name.to_partial_name())?;
store.find_loose(&name.to_partial_name_from_string())?;
store.find_loose(&name.to_partial_name_from_bstring())?;
store.find_loose(&name.to_full_name())?;
store.find_loose(name.to_full_name().as_ref())?;
store.find_loose(name.to_full_name().as_ref().as_partial_name())?;
store.find_loose(&PartialName::try_from(name.remote)?.join(name.branch)?)?;
store.find_loose(&PartialName::try_from("origin")?.join("main")?)?;
store.find_loose(&PartialName::try_from("origin")?.join(String::from("main"))?)?;
store.find_loose(&PartialName::try_from("origin")?.join("main")?)?;
Ok(())
}
}
mod loose {
use crate::file::store;
mod existing {
use std::path::Path;
use crate::file::store;
#[test]
fn success_and_failure() -> crate::Result {
let store = store()?;
for (partial_name, expected_path) in &[("main", Some("refs/heads/main")), ("does-not-exist", None)] {
let reference = store.find_loose(*partial_name);
match expected_path {
Some(expected_path) => assert_eq!(reference?.name.as_bstr(), expected_path),
None => match reference {
Ok(_) => panic!("Expected error"),
Err(git_ref::file::find::existing::Error::NotFound(name)) => {
assert_eq!(name, Path::new(*partial_name));
}
Err(err) => panic!("Unexpected err: {:?}", err),
},
}
}
Ok(())
}
}
#[test]
fn success() -> crate::Result {
let store = store()?;
for (partial_name, expected_path, expected_ref_kind) in &[
("dt1", "refs/tags/dt1", git_ref::Kind::Peeled), // tags before heads
("heads/dt1", "refs/heads/dt1", git_ref::Kind::Peeled),
("d1", "refs/d1", git_ref::Kind::Peeled), // direct refs before heads
("heads/d1", "refs/heads/d1", git_ref::Kind::Peeled),
("HEAD", "HEAD", git_ref::Kind::Symbolic), // it finds shortest paths first
("origin", "refs/remotes/origin/HEAD", git_ref::Kind::Symbolic),
("origin/HEAD", "refs/remotes/origin/HEAD", git_ref::Kind::Symbolic),
("origin/main", "refs/remotes/origin/main", git_ref::Kind::Peeled),
("t1", "refs/tags/t1", git_ref::Kind::Peeled),
("main", "refs/heads/main", git_ref::Kind::Peeled),
("heads/main", "refs/heads/main", git_ref::Kind::Peeled),
("refs/heads/main", "refs/heads/main", git_ref::Kind::Peeled),
] {
let reference = store.try_find_loose(*partial_name)?.expect("exists");
assert_eq!(reference.name.as_bstr(), expected_path);
assert_eq!(reference.target.to_ref().kind(), *expected_ref_kind);
}
Ok(())
}
#[test]
fn failure() -> crate::Result {
let store = store()?;
for (partial_name, reason, is_err) in &[
("foobar", "does not exist", false),
("broken", "does not parse", true),
("../escaping", "an invalid ref name", true),
] {
let reference = store.try_find_loose(*partial_name);
if *is_err {
assert!(reference.is_err(), "{}", reason);
} else {
let reference = reference?;
assert!(reference.is_none(), "{}", reason);
}
}
Ok(())
}
}