use super::commit::remove_settled;
use super::lfs_pre_push::{World, commit_directly, ref_of, wrapped, world};
use super::support::{Fixture, Observed, direct, fixture, git, observe, stderr_of};
const ENGINE_FAILURE_MARKERS: [&str; 3] = ["engine-failure", "content-unavailable", "Hint: if you are committing or pushing content"];
fn policy_world(fixture: &Fixture) -> World {
let world: World = world(fixture, false, None);
let policy: &str = "{ \"policies\": { \"final-newline\": \"error\" } }\n";
commit_directly(fixture, world.repo.as_path(), "cli-git.config.jsonc", policy);
git(fixture, world.repo.as_path(), &["push", "--quiet", "--no-verify", "origin", "main"]);
return world;
}
fn plain(fixture: &Fixture, world: &World, region: &[&str]) -> Observed {
return observe(direct(fixture).current_dir(world.repo.as_path()).args(region), b"");
}
fn assert_ends_as_git(fixture: &Fixture, world: &World, region: &[&str]) {
let expected: Observed = plain(fixture, world, region);
assert_ne!(expected.code, Some(0), "{region:?}: the case must be a push Git refuses: {}", stderr_of(&expected));
let before: String = ref_of(fixture, world.origin.as_path(), "refs/heads/main");
let pushed: Observed = wrapped(fixture, world.repo.as_path(), region);
let stderr: String = stderr_of(&pushed);
assert_eq!(pushed.code, expected.code, "{region:?}: {stderr}");
for marker in ENGINE_FAILURE_MARKERS {
assert!(!stderr.contains(marker), "{region:?} shows the wrapper's {marker:?}: {stderr}");
}
assert_eq!(stderr, stderr_of(&expected), "{region:?}: Git's message must be the whole answer");
assert_eq!(ref_of(fixture, world.origin.as_path(), "refs/heads/main"), before, "{region:?}: nothing may be published");
}
#[test]
fn deleting_a_branch_the_remote_does_not_have_ends_as_git_ends_it() {
let fixture: Fixture = fixture("refusal-delete-absent");
let world: World = policy_world(&fixture);
assert_ends_as_git(&fixture, &world, &["push", "origin", "--delete", "no-such-branch"]);
remove_settled(&fixture);
}
#[test]
fn a_source_that_names_nothing_ends_as_git_ends_it() {
let fixture: Fixture = fixture("refusal-source");
let world: World = policy_world(&fixture);
assert_ends_as_git(&fixture, &world, &["push", "origin", "no-such-source:main"]);
remove_settled(&fixture);
}
#[test]
fn a_destination_that_cannot_be_qualified_ends_as_git_ends_it() {
let fixture: Fixture = fixture("refusal-destination");
let world: World = policy_world(&fixture);
assert_ends_as_git(&fixture, &world, &["push", "origin", "HEAD~0:unqualified"]);
remove_settled(&fixture);
}
#[test]
fn a_remote_that_does_not_exist_ends_as_git_ends_it() {
let fixture: Fixture = fixture("refusal-remote");
let world: World = policy_world(&fixture);
assert_ends_as_git(&fixture, &world, &["push", "no-such-remote", "main"]);
remove_settled(&fixture);
}
#[test]
fn an_option_git_does_not_know_ends_as_git_ends_it() {
let fixture: Fixture = fixture("refusal-option");
let world: World = policy_world(&fixture);
assert_ends_as_git(&fixture, &world, &["push", "--no-such-option", "origin"]);
remove_settled(&fixture);
}
#[test]
fn options_that_cannot_be_combined_end_as_git_ends_them() {
let fixture: Fixture = fixture("refusal-combination");
let world: World = policy_world(&fixture);
assert_ends_as_git(&fixture, &world, &["push", "--all", "origin", "main"]);
remove_settled(&fixture);
}
#[test]
fn a_rejected_update_ends_as_git_ends_it() {
let fixture: Fixture = fixture("refusal-rejected");
let world: World = policy_world(&fixture);
git(&fixture, world.repo.as_path(), &["tag", "v1"]);
git(&fixture, world.repo.as_path(), &["push", "--quiet", "--no-verify", "origin", "v1"]);
commit_directly(&fixture, world.repo.as_path(), "later.txt", "later\n");
git(&fixture, world.repo.as_path(), &["tag", "--force", "v1"]);
let expected: Observed = plain(&fixture, &world, &["push", "origin", "v1"]);
let pushed: Observed = wrapped(&fixture, world.repo.as_path(), &["push", "origin", "v1"]);
let stderr: String = stderr_of(&pushed);
assert_eq!(pushed.code, expected.code, "{stderr}");
for marker in ENGINE_FAILURE_MARKERS {
assert!(!stderr.contains(marker), "the rejection shows the wrapper's {marker:?}: {stderr}");
}
let plain_text: String = stderr_of(&expected);
let rejection: &str = plain_text.lines().find(|line| { return line.contains("[rejected]"); }).expect("Git rejects the tag");
assert!(stderr.contains(rejection), "Git's rejection must be shown: {stderr}");
remove_settled(&fixture);
}