mod single { use crate::matching::baseline; #[test] fn fetch_only() { baseline::agrees_with_fetch_specs(Some("refs/heads/main")); baseline::agrees_with_fetch_specs(Some("heads/main")); baseline::agrees_with_fetch_specs(Some("main")); baseline::agrees_with_fetch_specs(Some("v0.0-f1")); baseline::agrees_with_fetch_specs(Some("tags/v0.0-f2")); baseline::of_objects_always_matches_if_the_server_has_the_object(Some( "78b1c1be9421b33a49a7a8176d93eeeafa112da1", )); baseline::of_objects_always_matches_if_the_server_has_the_object(Some( "9d2fab1a0ba3585d0bc50922bfdd04ebb59361df", )); } #[test] fn fetch_and_update() { baseline::of_objects_with_destinations_are_written_into_given_local_branches( Some("78b1c1be9421b33a49a7a8176d93eeeafa112da1:special"), ["78b1c1be9421b33a49a7a8176d93eeeafa112da1:refs/heads/special"], ); baseline::of_objects_with_destinations_are_written_into_given_local_branches( Some("78b1c1be9421b33a49a7a8176d93eeeafa112da1:1111111111111111111111111111111111111111"), ["78b1c1be9421b33a49a7a8176d93eeeafa112da1:refs/heads/1111111111111111111111111111111111111111"], ); baseline::of_objects_with_destinations_are_written_into_given_local_branches( Some("9d2fab1a0ba3585d0bc50922bfdd04ebb59361df:tags/special"), ["9d2fab1a0ba3585d0bc50922bfdd04ebb59361df:refs/tags/special"], ); baseline::of_objects_with_destinations_are_written_into_given_local_branches( Some("9d2fab1a0ba3585d0bc50922bfdd04ebb59361df:refs/tags/special"), ["9d2fab1a0ba3585d0bc50922bfdd04ebb59361df:refs/tags/special"], ); baseline::agrees_but_observable_refs_are_vague(Some("f1:origin/f1"), ["refs/heads/f1:refs/heads/origin/f1"]); baseline::agrees_but_observable_refs_are_vague( Some("f1:remotes/origin/f1"), ["refs/heads/f1:refs/remotes/origin/f1"], ); baseline::agrees_but_observable_refs_are_vague(Some("f1:notes/f1"), ["refs/heads/f1:refs/heads/notes/f1"]); baseline::agrees_with_fetch_specs(Some("+refs/heads/*:refs/remotes/origin/*")); baseline::agrees_with_fetch_specs(Some("refs/heads/f*:refs/remotes/origin/a*")); baseline::agrees_with_fetch_specs(Some("refs/heads/*1:refs/remotes/origin/*1")); }} mod multiple { use git_refspec::{ match_group::validate::Fix, parse::{Error, Operation}, }; use crate::matching::baseline; #[test] fn fetch_only() { baseline::agrees_with_fetch_specs(["main", "f1"]); baseline::agrees_with_fetch_specs(["heads/main", "heads/f1"]); baseline::agrees_with_fetch_specs(["refs/heads/main", "refs/heads/f1"]); baseline::agrees_with_fetch_specs(["heads/f1", "f2", "refs/heads/f3", "heads/main"]); baseline::agrees_with_fetch_specs(["f*:a*", "refs/heads/main"]); baseline::agrees_with_fetch_specs([ "refs/tags/*:refs/remotes/origin/*", "refs/heads/*:refs/remotes/origin/*", ]); baseline::agrees_with_fetch_specs(["refs/tags/*:refs/tags/*"]); } #[test] fn fetch_and_update_and_negations() { baseline::invalid_specs_fail_to_parse_where_git_shows_surprising_behaviour( ["refs/heads/f*:refs/remotes/origin/a*", "^f1"], Error::NegativePartialName, ); baseline::invalid_specs_fail_to_parse_where_git_shows_surprising_behaviour( ["heads/f2", "^refs/heads/f*:refs/remotes/origin/a*"], Error::NegativeWithDestination, ); baseline::agrees_with_fetch_specs(["refs/heads/f*:refs/remotes/origin/a*", "^refs/heads/f1"]); baseline::invalid_specs_fail_to_parse_where_git_shows_surprising_behaviour( ["^heads/f2", "refs/heads/f*:refs/remotes/origin/a*"], Error::NegativePartialName, ); baseline::agrees_with_fetch_specs(["^refs/heads/f2", "refs/heads/f*:refs/remotes/origin/a*"]); baseline::invalid_specs_fail_to_parse_where_git_shows_surprising_behaviour( ["^main", "refs/heads/*:refs/remotes/origin/*"], Error::NegativePartialName, ); baseline::agrees_with_fetch_specs(["^refs/heads/main", "refs/heads/*:refs/remotes/origin/*"]); baseline::agrees_with_fetch_specs(["refs/heads/*:refs/remotes/origin/*", "^refs/heads/main"]); } #[test] fn fetch_and_update_with_empty_lhs() { baseline::agrees_but_observable_refs_are_vague([":refs/heads/f1"], ["HEAD:refs/heads/f1"]); baseline::agrees_but_observable_refs_are_vague([":f1"], ["HEAD:refs/heads/f1"]); baseline::agrees_but_observable_refs_are_vague(["@:f1"], ["HEAD:refs/heads/f1"]); } #[test] fn fetch_and_update_head_to_head_never_updates_actual_head_ref() { baseline::agrees_but_observable_refs_are_vague(["@:HEAD"], ["HEAD:refs/heads/HEAD"]); } #[test] fn fetch_and_update_head_with_empty_rhs() { baseline::agrees_but_observable_refs_are_vague([":"], ["HEAD:"]); baseline::agrees_but_observable_refs_are_vague(["HEAD:"], ["HEAD:"]); baseline::agrees_but_observable_refs_are_vague(["@:"], ["HEAD:"]); } #[test] fn fetch_and_update_multiple_destinations() { baseline::agrees_with_fetch_specs([ "refs/heads/*:refs/remotes/origin/*", "refs/heads/main:refs/remotes/new-origin/main", ]); baseline::agrees_with_fetch_specs([ "refs/heads/*:refs/remotes/origin/*", "refs/heads/main:refs/remotes/origin/main", // duplicates are removed immediately. ]); } #[test] fn fetch_and_update_with_conflicts() { baseline::agrees_with_fetch_specs_validation_error( [ "refs/heads/f1:refs/remotes/origin/conflict", "refs/heads/f2:refs/remotes/origin/conflict", ], "Found 1 issue that prevents the refspec mapping to be used: \n\tConflicting destination \"refs/remotes/origin/conflict\" would be written by refs/heads/f1 (\"refs/heads/f1:refs/remotes/origin/conflict\"), refs/heads/f2 (\"refs/heads/f2:refs/remotes/origin/conflict\")", ); baseline::agrees_with_fetch_specs_validation_error( [ "refs/heads/f1:refs/remotes/origin/conflict2", "refs/heads/f2:refs/remotes/origin/conflict2", "refs/heads/f1:refs/remotes/origin/conflict", "refs/heads/f2:refs/remotes/origin/conflict", "refs/heads/f3:refs/remotes/origin/conflict", ], "Found 2 issues that prevent the refspec mapping to be used: \n\tConflicting destination \"refs/remotes/origin/conflict\" would be written by refs/heads/f1 (\"refs/heads/f1:refs/remotes/origin/conflict\"), refs/heads/f2 (\"refs/heads/f2:refs/remotes/origin/conflict\"), refs/heads/f3 (\"refs/heads/f3:refs/remotes/origin/conflict\")\n\tConflicting destination \"refs/remotes/origin/conflict2\" would be written by refs/heads/f1 (\"refs/heads/f1:refs/remotes/origin/conflict2\"), refs/heads/f2 (\"refs/heads/f2:refs/remotes/origin/conflict2\")", ); baseline::agrees_with_fetch_specs_validation_error( [ "refs/heads/f1:refs/remotes/origin/same", "refs/tags/v0.0-f1:refs/remotes/origin/same", ], "Found 1 issue that prevents the refspec mapping to be used: \n\tConflicting destination \"refs/remotes/origin/same\" would be written by refs/heads/f1 (\"refs/heads/f1:refs/remotes/origin/same\"), refs/tags/v0.0-f1 (\"refs/tags/v0.0-f1:refs/remotes/origin/same\")", ); baseline::agrees_with_fetch_specs_validation_error( [ "+refs/heads/*:refs/remotes/origin/*", "refs/heads/f1:refs/remotes/origin/f2", "refs/heads/f2:refs/remotes/origin/f1", ], "Found 2 issues that prevent the refspec mapping to be used: \n\tConflicting destination \"refs/remotes/origin/f1\" would be written by refs/heads/f1 (\"+refs/heads/*:refs/remotes/origin/*\"), refs/heads/f2 (\"refs/heads/f2:refs/remotes/origin/f1\")\n\tConflicting destination \"refs/remotes/origin/f2\" would be written by refs/heads/f2 (\"+refs/heads/*:refs/remotes/origin/*\"), refs/heads/f1 (\"refs/heads/f1:refs/remotes/origin/f2\")", ); } #[test] fn fetch_and_update_with_fixes() { let glob_spec = "refs/heads/f*:foo/f*"; let glob_spec_ref = git_refspec::parse(glob_spec.into(), Operation::Fetch).unwrap(); baseline::agrees_and_applies_fixes( [glob_spec, "f1:f1"], [ Fix::MappingWithPartialDestinationRemoved { name: "foo/f1".into(), spec: glob_spec_ref, }, Fix::MappingWithPartialDestinationRemoved { name: "foo/f2".into(), spec: glob_spec_ref, }, Fix::MappingWithPartialDestinationRemoved { name: "foo/f3".into(), spec: glob_spec_ref, }, ], ["refs/heads/f1:refs/heads/f1"], ) }}
mod single {
use crate::matching::baseline;
#[test]
fn fetch_only() {
baseline::agrees_with_fetch_specs(Some("refs/heads/main"));
baseline::agrees_with_fetch_specs(Some("heads/main"));
baseline::agrees_with_fetch_specs(Some("main"));
baseline::agrees_with_fetch_specs(Some("v0.0-f1"));
baseline::agrees_with_fetch_specs(Some("tags/v0.0-f2"));
baseline::of_objects_always_matches_if_the_server_has_the_object(Some(
"78b1c1be9421b33a49a7a8176d93eeeafa112da1",
));
baseline::of_objects_always_matches_if_the_server_has_the_object(Some(
"9d2fab1a0ba3585d0bc50922bfdd04ebb59361df",
));
}
#[test]
fn fetch_and_update() {
baseline::of_objects_with_destinations_are_written_into_given_local_branches(
Some("78b1c1be9421b33a49a7a8176d93eeeafa112da1:special"),
["78b1c1be9421b33a49a7a8176d93eeeafa112da1:refs/heads/special"],
);
baseline::of_objects_with_destinations_are_written_into_given_local_branches(
Some("78b1c1be9421b33a49a7a8176d93eeeafa112da1:1111111111111111111111111111111111111111"),
["78b1c1be9421b33a49a7a8176d93eeeafa112da1:refs/heads/1111111111111111111111111111111111111111"],
);
baseline::of_objects_with_destinations_are_written_into_given_local_branches(
Some("9d2fab1a0ba3585d0bc50922bfdd04ebb59361df:tags/special"),
["9d2fab1a0ba3585d0bc50922bfdd04ebb59361df:refs/tags/special"],
);
baseline::of_objects_with_destinations_are_written_into_given_local_branches(
Some("9d2fab1a0ba3585d0bc50922bfdd04ebb59361df:refs/tags/special"),
["9d2fab1a0ba3585d0bc50922bfdd04ebb59361df:refs/tags/special"],
);
baseline::agrees_but_observable_refs_are_vague(Some("f1:origin/f1"), ["refs/heads/f1:refs/heads/origin/f1"]);
baseline::agrees_but_observable_refs_are_vague(
Some("f1:remotes/origin/f1"),
["refs/heads/f1:refs/remotes/origin/f1"],
);
baseline::agrees_but_observable_refs_are_vague(Some("f1:notes/f1"), ["refs/heads/f1:refs/heads/notes/f1"]);
baseline::agrees_with_fetch_specs(Some("+refs/heads/*:refs/remotes/origin/*"));
baseline::agrees_with_fetch_specs(Some("refs/heads/f*:refs/remotes/origin/a*"));
baseline::agrees_with_fetch_specs(Some("refs/heads/*1:refs/remotes/origin/*1"));
}
}
mod multiple {
use git_refspec::{
match_group::validate::Fix,
parse::{Error, Operation},
};
use crate::matching::baseline;
#[test]
fn fetch_only() {
baseline::agrees_with_fetch_specs(["main", "f1"]);
baseline::agrees_with_fetch_specs(["heads/main", "heads/f1"]);
baseline::agrees_with_fetch_specs(["refs/heads/main", "refs/heads/f1"]);
baseline::agrees_with_fetch_specs(["heads/f1", "f2", "refs/heads/f3", "heads/main"]);
baseline::agrees_with_fetch_specs(["f*:a*", "refs/heads/main"]);
baseline::agrees_with_fetch_specs([
"refs/tags/*:refs/remotes/origin/*",
"refs/heads/*:refs/remotes/origin/*",
]);
baseline::agrees_with_fetch_specs(["refs/tags/*:refs/tags/*"]);
}
#[test]
fn fetch_and_update_and_negations() {
baseline::invalid_specs_fail_to_parse_where_git_shows_surprising_behaviour(
["refs/heads/f*:refs/remotes/origin/a*", "^f1"],
Error::NegativePartialName,
);
baseline::invalid_specs_fail_to_parse_where_git_shows_surprising_behaviour(
["heads/f2", "^refs/heads/f*:refs/remotes/origin/a*"],
Error::NegativeWithDestination,
);
baseline::agrees_with_fetch_specs(["refs/heads/f*:refs/remotes/origin/a*", "^refs/heads/f1"]);
baseline::invalid_specs_fail_to_parse_where_git_shows_surprising_behaviour(
["^heads/f2", "refs/heads/f*:refs/remotes/origin/a*"],
Error::NegativePartialName,
);
baseline::agrees_with_fetch_specs(["^refs/heads/f2", "refs/heads/f*:refs/remotes/origin/a*"]);
baseline::invalid_specs_fail_to_parse_where_git_shows_surprising_behaviour(
["^main", "refs/heads/*:refs/remotes/origin/*"],
Error::NegativePartialName,
);
baseline::agrees_with_fetch_specs(["^refs/heads/main", "refs/heads/*:refs/remotes/origin/*"]);
baseline::agrees_with_fetch_specs(["refs/heads/*:refs/remotes/origin/*", "^refs/heads/main"]);
}
#[test]
fn fetch_and_update_with_empty_lhs() {
baseline::agrees_but_observable_refs_are_vague([":refs/heads/f1"], ["HEAD:refs/heads/f1"]);
baseline::agrees_but_observable_refs_are_vague([":f1"], ["HEAD:refs/heads/f1"]);
baseline::agrees_but_observable_refs_are_vague(["@:f1"], ["HEAD:refs/heads/f1"]);
}
#[test]
fn fetch_and_update_head_to_head_never_updates_actual_head_ref() {
baseline::agrees_but_observable_refs_are_vague(["@:HEAD"], ["HEAD:refs/heads/HEAD"]);
}
#[test]
fn fetch_and_update_head_with_empty_rhs() {
baseline::agrees_but_observable_refs_are_vague([":"], ["HEAD:"]);
baseline::agrees_but_observable_refs_are_vague(["HEAD:"], ["HEAD:"]);
baseline::agrees_but_observable_refs_are_vague(["@:"], ["HEAD:"]);
}
#[test]
fn fetch_and_update_multiple_destinations() {
baseline::agrees_with_fetch_specs([
"refs/heads/*:refs/remotes/origin/*",
"refs/heads/main:refs/remotes/new-origin/main",
]);
baseline::agrees_with_fetch_specs([
"refs/heads/*:refs/remotes/origin/*",
"refs/heads/main:refs/remotes/origin/main", // duplicates are removed immediately.
]);
}
#[test]
fn fetch_and_update_with_conflicts() {
baseline::agrees_with_fetch_specs_validation_error(
[
"refs/heads/f1:refs/remotes/origin/conflict",
"refs/heads/f2:refs/remotes/origin/conflict",
],
"Found 1 issue that prevents the refspec mapping to be used: \n\tConflicting destination \"refs/remotes/origin/conflict\" would be written by refs/heads/f1 (\"refs/heads/f1:refs/remotes/origin/conflict\"), refs/heads/f2 (\"refs/heads/f2:refs/remotes/origin/conflict\")",
);
baseline::agrees_with_fetch_specs_validation_error(
[
"refs/heads/f1:refs/remotes/origin/conflict2",
"refs/heads/f2:refs/remotes/origin/conflict2",
"refs/heads/f1:refs/remotes/origin/conflict",
"refs/heads/f2:refs/remotes/origin/conflict",
"refs/heads/f3:refs/remotes/origin/conflict",
],
"Found 2 issues that prevent the refspec mapping to be used: \n\tConflicting destination \"refs/remotes/origin/conflict\" would be written by refs/heads/f1 (\"refs/heads/f1:refs/remotes/origin/conflict\"), refs/heads/f2 (\"refs/heads/f2:refs/remotes/origin/conflict\"), refs/heads/f3 (\"refs/heads/f3:refs/remotes/origin/conflict\")\n\tConflicting destination \"refs/remotes/origin/conflict2\" would be written by refs/heads/f1 (\"refs/heads/f1:refs/remotes/origin/conflict2\"), refs/heads/f2 (\"refs/heads/f2:refs/remotes/origin/conflict2\")",
);
baseline::agrees_with_fetch_specs_validation_error(
[
"refs/heads/f1:refs/remotes/origin/same",
"refs/tags/v0.0-f1:refs/remotes/origin/same",
],
"Found 1 issue that prevents the refspec mapping to be used: \n\tConflicting destination \"refs/remotes/origin/same\" would be written by refs/heads/f1 (\"refs/heads/f1:refs/remotes/origin/same\"), refs/tags/v0.0-f1 (\"refs/tags/v0.0-f1:refs/remotes/origin/same\")",
);
baseline::agrees_with_fetch_specs_validation_error(
[
"+refs/heads/*:refs/remotes/origin/*",
"refs/heads/f1:refs/remotes/origin/f2",
"refs/heads/f2:refs/remotes/origin/f1",
],
"Found 2 issues that prevent the refspec mapping to be used: \n\tConflicting destination \"refs/remotes/origin/f1\" would be written by refs/heads/f1 (\"+refs/heads/*:refs/remotes/origin/*\"), refs/heads/f2 (\"refs/heads/f2:refs/remotes/origin/f1\")\n\tConflicting destination \"refs/remotes/origin/f2\" would be written by refs/heads/f2 (\"+refs/heads/*:refs/remotes/origin/*\"), refs/heads/f1 (\"refs/heads/f1:refs/remotes/origin/f2\")",
);
}
#[test]
fn fetch_and_update_with_fixes() {
let glob_spec = "refs/heads/f*:foo/f*";
let glob_spec_ref = git_refspec::parse(glob_spec.into(), Operation::Fetch).unwrap();
baseline::agrees_and_applies_fixes(
[glob_spec, "f1:f1"],
[
Fix::MappingWithPartialDestinationRemoved {
name: "foo/f1".into(),
spec: glob_spec_ref,
},
Fix::MappingWithPartialDestinationRemoved {
name: "foo/f2".into(),
spec: glob_spec_ref,
},
Fix::MappingWithPartialDestinationRemoved {
name: "foo/f3".into(),
spec: glob_spec_ref,
},
],
["refs/heads/f1:refs/heads/f1"],
)
}
}