use super::*;
use crate::test_support::{executable, fixture, remove};
use std::path::PathBuf;
fn snapshot(entries: &[(&str, &str, &str)]) -> ConfigSnapshot {
let mut listing: Vec<u8> = Vec::new();
for (scope, key, value) in entries {
listing.extend_from_slice(scope.as_bytes());
listing.push(0);
listing.extend_from_slice(key.as_bytes());
listing.push(b'\n');
listing.extend_from_slice(value.as_bytes());
listing.push(0);
}
return ConfigSnapshot::parse(listing.as_slice(), true).expect("listing parses");
}
#[test]
fn lfs_keys_of_the_repository_mark_it_as_using_lfs() {
assert!(uses_lfs(&snapshot(&[("local", "lfs.repositoryformatversion", "0")])));
assert!(uses_lfs(&snapshot(&[("local", "lfs.https://example.invalid/x.git/info/lfs.access", "basic")])));
assert!(uses_lfs(&snapshot(&[("local", "filter.lfs.process", "git-lfs filter-process")])));
assert!(uses_lfs(&snapshot(&[("worktree", "lfs.url", "http://127.0.0.1:1")])));
assert!(uses_lfs(&snapshot(&[("command", "lfs.url", "http://127.0.0.1:1")])));
assert!(uses_lfs(&snapshot(&[("system", "core.autocrlf", "false"), ("local", "lfs.url", "x")])));
}
#[test]
fn lfs_keys_of_the_machine_or_account_do_not_mark_a_repository_as_using_lfs() {
assert!(!uses_lfs(&snapshot(&[("global", "filter.lfs.process", "git-lfs filter-process")])));
assert!(!uses_lfs(&snapshot(&[("global", "lfs.customtransfer.xet.path", "git-xet")])));
assert!(!uses_lfs(&snapshot(&[("system", "filter.lfs.clean", "git-lfs clean")])));
assert!(!uses_lfs(&snapshot(&[
("global", "filter.lfs.smudge", "git-lfs smudge"),
("local", "core.bare", "false"),
])));
}
#[test]
fn other_configuration_does_not_mark_the_repository_as_using_lfs() {
assert!(!uses_lfs(&snapshot(&[])));
assert!(!uses_lfs(&snapshot(&[("local", "core.hookspath", "hooks")])));
assert!(!uses_lfs(&snapshot(&[("local", "hook.lfs.event", "pre-push")])));
assert!(!uses_lfs(&snapshot(&[("local", "filter.lfsx.process", "x")])));
assert!(!uses_lfs(&snapshot(&[("local", "lfsextra.url", "x")])));
assert!(!uses_lfs(&snapshot(&[("local", "filter.other.clean", "x")])));
}
#[test]
fn the_callers_switch_off_is_read_from_the_last_setting() {
let prefix = |words: &[&str]| -> Vec<OsString> { return words.iter().map(OsString::from).collect() };
assert!(hook_switched_off(&prefix(&["-c", "hook.cli-git-lfs-pre-push.enabled=false"]), &[]));
assert!(hook_switched_off(&prefix(&["-c", "hook.cli-git-lfs-pre-push.enabled=no"]), &[]));
assert!(hook_switched_off(&prefix(&["-c", "hook.cli-git-lfs-pre-push.enabled=0"]), &[]));
assert!(hook_switched_off(&prefix(&["-c", "hook.cli-git-lfs-pre-push.enabled=off"]), &[]));
assert!(hook_switched_off(&prefix(&["-c", "hook.cli-git-lfs-pre-push.enabled="]), &[]));
assert!(!hook_switched_off(&prefix(&[
"-c",
"hook.cli-git-lfs-pre-push.enabled=false",
"-c",
"hook.cli-git-lfs-pre-push.enabled=true"
]), &[]));
assert!(!hook_switched_off(&prefix(&["-c", "hook.other.enabled=false"]), &[]));
assert!(hook_switched_off(&prefix(&["-c", "HOOK.cli-git-lfs-pre-push.ENABLED=false"]), &[]), "section and variable ignore case");
assert!(!hook_switched_off(&prefix(&["-c", "hook.CLI-GIT-LFS-PRE-PUSH.enabled=false"]), &[]), "the subsection is exact");
assert!(
!hook_switched_off(&prefix(&["-c", "hook.cli-git-lfs-pre-push.enabled=false", "-c", "hook.cli-git-lfs-pre-push.enabled"]), &[]),
"a later name without a value is the boolean true"
);
assert!(!hook_switched_off(&prefix(&["-C", "dir"]), &[]));
assert!(!hook_switched_off(&prefix(&["-c"]), &[]));
assert!(!hook_switched_off(&[], &[]));
}
#[test]
fn the_lookup_finds_only_an_executable_file_in_a_path_directory() {
let root: PathBuf = fixture("lfs-path-lookup");
let with_program: PathBuf = root.join("with");
let without: PathBuf = root.join("without");
let plain: PathBuf = root.join("plain");
let directory_named_so: PathBuf = root.join("dir");
for directory in [&with_program, &without, &plain, &directory_named_so] {
std::fs::create_dir(directory).expect("directory");
}
executable(with_program.join("git-lfs").as_path(), b"#!/bin/sh\n");
std::fs::write(plain.join("git-lfs"), b"text").expect("plain file");
std::fs::create_dir(directory_named_so.join("git-lfs")).expect("directory with the program's name");
let joined = |directories: &[&PathBuf]| {
return std::env::join_paths(directories).expect("joined");
};
assert!(program_on_path(joined(&[&without, &with_program]).as_os_str()));
assert!(!program_on_path(joined(&[&without, &plain, &directory_named_so]).as_os_str()));
assert!(!program_on_path(OsStr::new("")));
remove(root.as_path());
}
#[test]
fn the_missing_program_message_names_the_cause_and_every_way_forward() {
let message: String = missing_program_message();
for needle in [
"stopped before it sent anything",
"`git-lfs` was not found in any directory of PATH",
"install Git LFS",
"git lfs uninstall",
"git push --no-verify",
"git lfs push --all <remote>",
] {
assert!(message.contains(needle), "{needle}: {message}");
}
assert!(!message.contains('\u{2014}') && !message.contains('\u{2013}'));
}
#[test]
fn the_failure_message_says_nothing_was_published_and_names_every_way_forward() {
let message: String = failed_message("exited with status 2");
for needle in [
"`git-lfs push` exited with status 2",
"this push was not started and nothing was published",
"`lfs.url`",
"git lfs push --all <remote>",
"git push --no-verify",
"GIT_LFS_SKIP_PUSH=1",
] {
assert!(message.contains(needle), "{needle}: {message}");
}
}
#[test]
fn the_skip_variable_is_read_as_a_boolean() {
let with = |value: &str| -> Vec<(OsString, OsString)> {
return vec![(OsString::from("GIT_LFS_SKIP_PUSH"), OsString::from(value))];
};
for truthy in ["1", "t", "T", "true", "TRUE", "y", "yes", "on"] {
assert!(skip_requested(with(truthy).as_slice()), "{truthy}");
}
for other in ["0", "false", "", "no", "off", "2"] {
assert!(!skip_requested(with(other).as_slice()), "{other:?}");
}
assert!(!skip_requested(&[]));
}
#[test]
fn a_relative_path_entry_is_found_as_an_absolute_file() {
let root = fixture("lfs-relative-path");
let bin: PathBuf = root.join("bin");
std::fs::create_dir(&bin).expect("bin directory");
executable(bin.join("git-lfs").as_path(), b"#!/bin/sh\n");
std::env::set_current_dir(&root).expect("the fixture is the lookup directory");
let found: PathBuf = find_program(OsStr::new("bin")).expect("found through the relative entry");
assert!(found.is_absolute(), "{found:?}");
assert_eq!(found, root.join("bin/git-lfs"));
assert!(program_on_path(OsStr::new("bin")));
remove(root.as_path());
}