Sebastian Thieladdress auto-review048d4a54 months agoHistory
156 lines · 6.1 KB · Rust
RawDownload
mod from_refs {    use gix_protocol::fetch::{RefMap, refmap};    use gix_transport::client::Capabilities;     #[test]    fn sha1_capability_is_honored() {        let caps = caps_with(b"symref=HEAD:refs/heads/main object-format=sha1 agent=git/2.54.0");        let map = RefMap::from_refs(Vec::new(), &caps, ctx()).expect("known format");        assert_eq!(            map.object_hash,            gix_hash::Kind::Sha1,            "An `object-format=sha1` capability resolves to `gix_hash::Kind::Sha1` on the resulting RefMap"        );    }     #[cfg(feature = "sha256")]    #[test]    fn sha256_capability_is_honored() {        let caps = caps_with(b"symref=HEAD:refs/heads/main object-format=sha256 agent=git/2.54.0");        let map = RefMap::from_refs(Vec::new(), &caps, ctx()).expect("known format");        assert_eq!(            map.object_hash,            gix_hash::Kind::Sha256,            "An `object-format=sha256` capability resolves to `gix_hash::Kind::Sha256`, so Sha256 servers            can be talked to without falling back to Sha1"        );    }     #[test]    fn unknown_object_format_errors() {        let caps = caps_with(b"symref=HEAD:refs/heads/main object-format=sha999 agent=git/2.54.0");        let err = RefMap::from_refs(Vec::new(), &caps, ctx()).expect_err("unknown format must error");        assert!(            matches!(err, refmap::init::Error::UnknownObjectFormat { ref format } if format == "sha999"),            "Any `object-format` value we don't recognize must surface as an `UnknownObjectFormat` error            rather than silently defaulting to Sha1, so callers can refuse to fetch from unsupported servers"        );    }     #[test]    fn missing_object_format_defaults_to_sha1() {        let caps = caps_with(b"symref=HEAD:refs/heads/main agent=git/2.54.0");        let map = RefMap::from_refs(Vec::new(), &caps, ctx()).expect("implicit sha1");        assert_eq!(            map.object_hash,            gix_hash::Kind::Sha1,            "Servers that omit `object-format` are implicitly Sha1, so the RefMap should reflect that"        );    }     fn caps_with(after_nul: &[u8]) -> Capabilities {        let mut bytes: Vec<u8> = b"7814e8a05a59c0cf5fb186661d1551c75d1299b5 HEAD\0".to_vec();        bytes.extend_from_slice(after_nul);        Capabilities::from_bytes(&bytes).expect("valid capabilities line").0    }     fn ctx() -> refmap::init::Context {        refmap::init::Context {            fetch_refspecs: Vec::new(),            extra_refspecs: Vec::new(),        }    }} mod is_missing_required_mapping {    use gix_protocol::{        fetch::{            RefMap,            refmap::{Mapping, Source, SpecIndex},        },        handshake::Ref,    };     fn fetch_spec(spec: &str) -> gix_refspec::RefSpec {        gix_refspec::parse(spec.into(), gix_refspec::parse::Operation::Fetch)            .expect("valid")            .to_owned()    }     /// If the server advertised refs but none of them matched at all, callers should treat this as a    /// missing required mapping instead of silently proceeding with an empty result.    ///    /// This covers the case where an exact fetch refspec like `refs/heads/main` was expected to match    /// something on the remote, but the only advertised ref was unrelated.    #[test]    fn is_true_if_remote_refs_exist_but_nothing_mapped() {        let map = RefMap {            refspecs: vec![fetch_spec("refs/heads/main")],            remote_refs: vec![Ref::Direct {                full_ref_name: "refs/heads/other".into(),                object: gix_hash::ObjectId::null(gix_hash::Kind::Sha1),            }],            object_hash: gix_hash::Kind::Sha1,            ..Default::default()        };         assert!(map.is_missing_required_mapping());    }     /// Exact explicit refspecs like `HEAD` still require an explicit mapping, even if unrelated implicit    /// mappings exist due to extra refspecs such as tag following.    ///    /// Returning `true` here ensures callers don't mistake an implicit-only result for a successful match    /// of the user's explicit fetch request.    #[test]    fn is_true_if_only_implicit_mappings_exist_for_exact_refspecs() {        let map = RefMap {            mappings: vec![Mapping {                remote: Source::ObjectId(gix_hash::ObjectId::null(gix_hash::Kind::Sha1)),                local: Some("refs/remotes/origin/main".into()),                spec_index: SpecIndex::Implicit(0),            }],            refspecs: vec![fetch_spec("HEAD")],            extra_refspecs: vec![fetch_spec("refs/tags/*:refs/tags/*")],            object_hash: gix_hash::Kind::Sha1,            ..Default::default()        };         assert!(map.is_missing_required_mapping());    }     /// Wildcard refspecs are allowed to match nothing without being considered an error.    ///    /// They express interest in a namespace rather than in one required ref, so an empty result here means    /// "nothing matched" instead of "a required mapping is missing".    #[test]    fn is_false_if_wildcards_are_the_only_unmatched_explicit_refspecs() {        let map = RefMap {            refspecs: vec![fetch_spec("refs/heads/*:refs/remotes/origin/*")],            object_hash: gix_hash::Kind::Sha1,            ..Default::default()        };         assert!(!map.is_missing_required_mapping());    }     /// Once at least one explicit refspec produced a mapping, the helper must report success.    ///    /// This is the common case of an exact refspec matching as intended, so callers should continue with    /// negotiation or ref updates instead of raising a no-mapping error.    #[test]    fn is_false_if_an_explicit_mapping_exists() {        let map = RefMap {            mappings: vec![Mapping {                remote: Source::ObjectId(gix_hash::ObjectId::null(gix_hash::Kind::Sha1)),                local: Some("refs/remotes/origin/main".into()),                spec_index: SpecIndex::ExplicitInRemote(0),            }],            refspecs: vec![fetch_spec("refs/heads/main")],            object_hash: gix_hash::Kind::Sha1,            ..Default::default()        };         assert!(!map.is_missing_required_mapping());    }}