2015-11-16 05:25:01 +00:00
|
|
|
use common::util::*;
|
|
|
|
|
|
|
|
static UTIL_NAME: &'static str = "ln";
|
2016-07-29 21:26:32 +00:00
|
|
|
fn at_and_ucmd() -> (AtPath, UCommand) {
|
|
|
|
let ts = TestScenario::new(UTIL_NAME);
|
|
|
|
let ucmd = ts.ucmd();
|
|
|
|
(ts.fixtures, ucmd)
|
|
|
|
}
|
2015-11-16 05:25:01 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_existing_file() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let file = "test_symlink_existing_file";
|
|
|
|
let link = "test_symlink_existing_file_link";
|
|
|
|
|
|
|
|
at.touch(file);
|
|
|
|
|
|
|
|
let result = ucmd.args(&["-s", file, link]).run();
|
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert!(result.success);
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), file);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_dangling_file() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let file = "test_symlink_dangling_file";
|
|
|
|
let link = "test_symlink_dangling_file_link";
|
|
|
|
|
|
|
|
let result = ucmd.args(&["-s", file, link]).run();
|
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert!(result.success);
|
|
|
|
assert!(!at.file_exists(file));
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), file);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_existing_directory() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let dir = "test_symlink_existing_dir";
|
|
|
|
let link = "test_symlink_existing_dir_link";
|
|
|
|
|
|
|
|
at.mkdir(dir);
|
|
|
|
|
|
|
|
let result = ucmd.args(&["-s", dir, link]).run();
|
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert!(result.success);
|
|
|
|
assert!(at.dir_exists(dir));
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_dangling_directory() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let dir = "test_symlink_dangling_dir";
|
|
|
|
let link = "test_symlink_dangling_dir_link";
|
|
|
|
|
|
|
|
let result = ucmd.args(&["-s", dir, link]).run();
|
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert!(result.success);
|
|
|
|
assert!(!at.dir_exists(dir));
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_circular() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let link = "test_symlink_circular";
|
|
|
|
|
|
|
|
let result = ucmd.args(&["-s", link]).run();
|
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert!(result.success);
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), link);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_dont_overwrite() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let file = "test_symlink_dont_overwrite";
|
|
|
|
let link = "test_symlink_dont_overwrite_link";
|
|
|
|
|
|
|
|
at.touch(file);
|
|
|
|
at.touch(link);
|
|
|
|
|
|
|
|
let result = ucmd.args(&["-s", file, link]).run();
|
|
|
|
assert!(!result.success);
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
assert!(at.file_exists(link));
|
|
|
|
assert!(!at.is_symlink(link));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_overwrite_force() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let file_a = "test_symlink_overwrite_force_a";
|
|
|
|
let file_b = "test_symlink_overwrite_force_b";
|
|
|
|
let link = "test_symlink_overwrite_force_link";
|
|
|
|
|
|
|
|
// Create symlink
|
|
|
|
at.symlink(file_a, link);
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), file_a);
|
|
|
|
|
|
|
|
// Force overwrite of existing symlink
|
|
|
|
let result = ucmd.args(&["--force", "-s", file_b, link]).run();
|
|
|
|
assert!(result.success);
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), file_b);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_interactive() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let scene = TestScenario::new(UTIL_NAME);
|
|
|
|
let at = &scene.fixtures;
|
2015-11-16 05:25:01 +00:00
|
|
|
let file = "test_symlink_interactive_file";
|
|
|
|
let link = "test_symlink_interactive_file_link";
|
|
|
|
|
|
|
|
at.touch(file);
|
|
|
|
at.touch(link);
|
|
|
|
|
2016-07-29 21:26:32 +00:00
|
|
|
let result1 = scene.ucmd()
|
2015-11-16 05:25:01 +00:00
|
|
|
.args(&["-i", "-s", file, link])
|
2016-02-17 05:03:52 +00:00
|
|
|
.run_piped_stdin("n");
|
2015-11-16 05:25:01 +00:00
|
|
|
|
|
|
|
assert_empty_stderr!(result1);
|
|
|
|
assert!(result1.success);
|
|
|
|
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
assert!(!at.is_symlink(link));
|
|
|
|
|
2016-07-29 21:26:32 +00:00
|
|
|
let result2 = scene.ucmd()
|
2015-11-16 05:25:01 +00:00
|
|
|
.args(&["-i", "-s", file, link])
|
2016-02-17 05:03:52 +00:00
|
|
|
.run_piped_stdin("Yesh");
|
2015-11-16 05:25:01 +00:00
|
|
|
|
|
|
|
assert_empty_stderr!(result2);
|
|
|
|
assert!(result2.success);
|
|
|
|
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), file);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_simple_backup() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let file = "test_symlink_simple_backup";
|
|
|
|
let link = "test_symlink_simple_backup_link";
|
|
|
|
|
|
|
|
at.touch(file);
|
|
|
|
at.symlink(file, link);
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), file);
|
|
|
|
|
|
|
|
let result = ucmd.args(&["-b", "-s", file, link]).run();
|
|
|
|
|
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert!(result.success);
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), file);
|
|
|
|
|
|
|
|
let backup = &format!("{}~", link);
|
|
|
|
assert!(at.is_symlink(backup));
|
|
|
|
assert_eq!(at.resolve_link(backup), file);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_custom_backup_suffix() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let file = "test_symlink_custom_backup_suffix";
|
|
|
|
let link = "test_symlink_custom_backup_suffix_link";
|
|
|
|
let suffix = "super-suffix-of-the-century";
|
|
|
|
|
|
|
|
at.touch(file);
|
|
|
|
at.symlink(file, link);
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), file);
|
|
|
|
|
|
|
|
let arg = &format!("--suffix={}", suffix);
|
|
|
|
let result = ucmd.args(&["-b", arg, "-s", file, link]).run();
|
|
|
|
|
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert!(result.success);
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), file);
|
|
|
|
|
|
|
|
let backup = &format!("{}{}", link, suffix);
|
|
|
|
assert!(at.is_symlink(backup));
|
|
|
|
assert_eq!(at.resolve_link(backup), file);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_backup_numbering() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let file = "test_symlink_backup_numbering";
|
|
|
|
let link = "test_symlink_backup_numbering_link";
|
|
|
|
|
|
|
|
at.touch(file);
|
|
|
|
at.symlink(file, link);
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), file);
|
|
|
|
|
|
|
|
let result = ucmd.args(&["-s", "--backup=t", file, link]).run();
|
|
|
|
|
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert!(result.success);
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), file);
|
|
|
|
|
|
|
|
let backup = &format!("{}.~1~", link);
|
|
|
|
assert!(at.is_symlink(backup));
|
|
|
|
assert_eq!(at.resolve_link(backup), file);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_existing_backup() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let file = "test_symlink_existing_backup";
|
|
|
|
let link = "test_symlink_existing_backup_link";
|
|
|
|
let link_backup = "test_symlink_existing_backup_link.~1~";
|
|
|
|
let resulting_backup = "test_symlink_existing_backup_link.~2~";
|
|
|
|
|
|
|
|
// Create symlink and verify
|
|
|
|
at.touch(file);
|
|
|
|
at.symlink(file, link);
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
assert!(at.is_symlink(link));
|
|
|
|
assert_eq!(at.resolve_link(link), file);
|
|
|
|
|
|
|
|
// Create backup symlink and verify
|
|
|
|
at.symlink(file, link_backup);
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
assert!(at.is_symlink(link_backup));
|
|
|
|
assert_eq!(at.resolve_link(link_backup), file);
|
|
|
|
|
|
|
|
let result = ucmd.args(&["-s", "--backup=nil", file, link]).run();
|
|
|
|
|
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert!(result.success);
|
|
|
|
assert!(at.file_exists(file));
|
|
|
|
|
|
|
|
assert!(at.is_symlink(link_backup));
|
|
|
|
assert_eq!(at.resolve_link(link_backup), file);
|
|
|
|
|
|
|
|
assert!(at.is_symlink(resulting_backup));
|
|
|
|
assert_eq!(at.resolve_link(resulting_backup), file);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_target_dir() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let dir = "test_ln_target_dir_dir";
|
|
|
|
let file_a = "test_ln_target_dir_file_a";
|
|
|
|
let file_b = "test_ln_target_dir_file_b";
|
|
|
|
|
|
|
|
at.touch(file_a);
|
|
|
|
at.touch(file_b);
|
|
|
|
at.mkdir(dir);
|
|
|
|
|
|
|
|
let result = ucmd.args(&["-s", "-t", dir, file_a, file_b]).run();
|
|
|
|
|
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert!(result.success);
|
|
|
|
|
|
|
|
let file_a_link = &format!("{}/{}", dir, file_a);
|
|
|
|
assert!(at.is_symlink(file_a_link));
|
|
|
|
assert_eq!(at.resolve_link(file_a_link), file_a);
|
|
|
|
|
|
|
|
let file_b_link = &format!("{}/{}", dir, file_b);
|
|
|
|
assert!(at.is_symlink(file_b_link));
|
|
|
|
assert_eq!(at.resolve_link(file_b_link), file_b);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_overwrite_dir() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let path_a = "test_symlink_overwrite_dir_a";
|
|
|
|
let path_b = "test_symlink_overwrite_dir_b";
|
|
|
|
|
|
|
|
at.touch(path_a);
|
|
|
|
at.mkdir(path_b);
|
|
|
|
|
|
|
|
let result = ucmd.args(&["-s", "-T", path_a, path_b]).run();
|
|
|
|
|
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert!(result.success);
|
|
|
|
|
|
|
|
assert!(at.file_exists(path_a));
|
|
|
|
assert!(at.is_symlink(path_b));
|
|
|
|
assert_eq!(at.resolve_link(path_b), path_a);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_overwrite_nonempty_dir() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let path_a = "test_symlink_overwrite_nonempty_dir_a";
|
|
|
|
let path_b = "test_symlink_overwrite_nonempty_dir_b";
|
|
|
|
let dummy = "test_symlink_overwrite_nonempty_dir_b/file";
|
|
|
|
|
|
|
|
at.touch(path_a);
|
|
|
|
at.mkdir(path_b);
|
|
|
|
at.touch(dummy);
|
|
|
|
|
|
|
|
let result = ucmd.args(&["-v", "-T", "-s", path_a, path_b]).run();
|
|
|
|
|
|
|
|
// Not same error as GNU; the error message is a Rust builtin
|
|
|
|
// TODO: test (and implement) correct error message (or at least decide whether to do so)
|
|
|
|
// Current: "ln: error: Directory not empty (os error 66)"
|
|
|
|
// GNU: "ln: cannot link 'a' to 'b': Directory not empty"
|
|
|
|
assert!(result.stderr.len() > 0);
|
|
|
|
|
|
|
|
// Verbose output for the link should not be shown on failure
|
|
|
|
assert!(result.stdout.len() == 0);
|
|
|
|
|
|
|
|
assert!(!result.success);
|
|
|
|
assert!(at.file_exists(path_a));
|
|
|
|
assert!(at.dir_exists(path_b));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_errors() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let (at, mut ucmd) = at_and_ucmd();
|
2015-11-16 05:25:01 +00:00
|
|
|
let dir = "test_symlink_errors_dir";
|
|
|
|
let file_a = "test_symlink_errors_file_a";
|
|
|
|
let file_b = "test_symlink_errors_file_b";
|
|
|
|
|
|
|
|
at.mkdir(dir);
|
|
|
|
at.touch(file_a);
|
|
|
|
at.touch(file_b);
|
|
|
|
|
|
|
|
// $ ln -T -t a b
|
|
|
|
// ln: cannot combine --target-directory (-t) and --no-target-directory (-T)
|
|
|
|
let result = ucmd.args(&["-T", "-t", dir, file_a, file_b]).run();
|
|
|
|
assert_eq!(result.stderr,
|
|
|
|
"ln: error: cannot combine --target-directory (-t) and --no-target-directory \
|
|
|
|
(-T)\n");
|
|
|
|
assert!(!result.success);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_symlink_verbose() {
|
2016-07-29 21:26:32 +00:00
|
|
|
let scene = TestScenario::new(UTIL_NAME);
|
|
|
|
let at = &scene.fixtures;
|
2015-11-16 05:25:01 +00:00
|
|
|
let file_a = "test_symlink_verbose_file_a";
|
|
|
|
let file_b = "test_symlink_verbose_file_b";
|
|
|
|
|
|
|
|
at.touch(file_a);
|
|
|
|
|
2016-07-29 21:26:32 +00:00
|
|
|
let result = scene.ucmd().args(&["-v", file_a, file_b]).run();
|
2015-11-16 05:25:01 +00:00
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert_eq!(result.stdout, format!("'{}' -> '{}'\n", file_b, file_a));
|
|
|
|
assert!(result.success);
|
|
|
|
|
|
|
|
at.touch(file_b);
|
|
|
|
|
2016-07-29 21:26:32 +00:00
|
|
|
let result = scene.ucmd().args(&["-v", "-b", file_a, file_b]).run();
|
2015-11-16 05:25:01 +00:00
|
|
|
assert_empty_stderr!(result);
|
|
|
|
assert_eq!(result.stdout,
|
|
|
|
format!("'{}' -> '{}' (backup: '{}~')\n", file_b, file_a, file_b));
|
|
|
|
assert!(result.success);
|
|
|
|
}
|